All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] reserved-memory regions/CMA in devicetree, again
@ 2014-02-04 12:09 ` Marek Szyprowski
  0 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-04 12:09 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linaro-mm-sig, devicetree, linux-doc
  Cc: Marek Szyprowski, Kyungmin Park, Benjamin Herrenschmidt,
	Arnd Bergmann, Michal Nazarewicz, Grant Likely, Tomasz Figa,
	Sascha Hauer, Laura Abbott, Rob Herring, Olof Johansson,
	Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
	Tomasz Figa, Kumar Gala, Nishanth Peethambaran, Marc,
	Josh Cartwright

Hi all!

This is an updated version of the second attempt to add basic support
for dynamic allocation of memory reserved regions defined in device
tree.

The initial code for this feature were posted here [1], merged as commit
9d8eab7af79cb4ce2de5de39f82c455b1f796963 ("drivers: of: add
initialization code for dma reserved memory") and later reverted by
commit 1931ee143b0ab72924944bc06e363d837ba05063. For more information,
see [2]. Finally a new bindings has been proposed [3] and Josh
Cartwright a few days ago prepared some code which implements those
bindings [4]. This finally pushed me again to find some time to finish
this task and review the code. Josh agreed to give me the ownership of
this series to continue preparing them for mainline inclusion.

For more information please refer to the changlelog below.

[1]: http://lkml.kernel.org/g/1377527959-5080-1-git-send-email-m.szyprowski@samsung.com
[2]: http://lkml.kernel.org/g/1381476448-14548-1-git-send-email-m.szyprowski@samsung.com
[3]: http://lkml.kernel.org/g/20131030134702.19B57C402A0@trevor.secretlab.ca
[4]: http://thread.gmane.org/gmane.linux.documentation/19579

Changelog:

v2:
- removed copying of the node name
- split shared-dma-pool handling into separate files (one for CMA and one
  for dma_declare_coherent based implementations) for making the code easier
  to understand
- added support for AMBA devices, changed prototypes to use struct decice
  instead of struct platform_device
- renamed some functions to better match other names used in drivers/of/
- restructured the rest of the code a bit for better readability
- added 'reusable' property to exmaple linux,cma node in documentation
- exclusive dma (dma_coherent) is used for only handling 'shared-dma-pool'
  regions without 'reusable' property and CMA is used only for handling
  'shared-dma-pool' regions with 'reusable' property.

v1: http://thread.gmane.org/gmane.linux.documentation/19579
- initial version prepared by Josh Cartwright

Summary:

Grant Likely (1):
  of: document bindings for reserved-memory nodes

Josh Cartwright (2):
  drivers: of: implement reserved-memory handling for dma
  drivers: of: implement reserved-memory handling for cma

Marek Szyprowski (2):
  drivers: of: add initialization code for reserved memory
  ARM: init: add support for reserved memory defined by device tree

 .../bindings/reserved-memory/reserved-memory.txt   |  138 ++++++++++++
 arch/arm/mm/init.c                                 |    3 +
 drivers/of/Kconfig                                 |   20 ++
 drivers/of/Makefile                                |    3 +
 drivers/of/of_reserved_mem.c                       |  219 ++++++++++++++++++++
 drivers/of/of_reserved_mem_cma.c                   |   75 +++++++
 drivers/of/of_reserved_mem_dma.c                   |   78 +++++++
 drivers/of/platform.c                              |    7 +
 include/asm-generic/vmlinux.lds.h                  |   11 +
 include/linux/of_reserved_mem.h                    |   62 ++++++
 10 files changed, 616 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
 create mode 100644 drivers/of/of_reserved_mem.c
 create mode 100644 drivers/of/of_reserved_mem_cma.c
 create mode 100644 drivers/of/of_reserved_mem_dma.c
 create mode 100644 include/linux/of_reserved_mem.h

-- 
1.7.9.5


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

* [PATCH v2 0/5] reserved-memory regions/CMA in devicetree, again
@ 2014-02-04 12:09 ` Marek Szyprowski
  0 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-04 12:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all!

This is an updated version of the second attempt to add basic support
for dynamic allocation of memory reserved regions defined in device
tree.

The initial code for this feature were posted here [1], merged as commit
9d8eab7af79cb4ce2de5de39f82c455b1f796963 ("drivers: of: add
initialization code for dma reserved memory") and later reverted by
commit 1931ee143b0ab72924944bc06e363d837ba05063. For more information,
see [2]. Finally a new bindings has been proposed [3] and Josh
Cartwright a few days ago prepared some code which implements those
bindings [4]. This finally pushed me again to find some time to finish
this task and review the code. Josh agreed to give me the ownership of
this series to continue preparing them for mainline inclusion.

For more information please refer to the changlelog below.

[1]: http://lkml.kernel.org/g/1377527959-5080-1-git-send-email-m.szyprowski at samsung.com
[2]: http://lkml.kernel.org/g/1381476448-14548-1-git-send-email-m.szyprowski at samsung.com
[3]: http://lkml.kernel.org/g/20131030134702.19B57C402A0 at trevor.secretlab.ca
[4]: http://thread.gmane.org/gmane.linux.documentation/19579

Changelog:

v2:
- removed copying of the node name
- split shared-dma-pool handling into separate files (one for CMA and one
  for dma_declare_coherent based implementations) for making the code easier
  to understand
- added support for AMBA devices, changed prototypes to use struct decice
  instead of struct platform_device
- renamed some functions to better match other names used in drivers/of/
- restructured the rest of the code a bit for better readability
- added 'reusable' property to exmaple linux,cma node in documentation
- exclusive dma (dma_coherent) is used for only handling 'shared-dma-pool'
  regions without 'reusable' property and CMA is used only for handling
  'shared-dma-pool' regions with 'reusable' property.

v1: http://thread.gmane.org/gmane.linux.documentation/19579
- initial version prepared by Josh Cartwright

Summary:

Grant Likely (1):
  of: document bindings for reserved-memory nodes

Josh Cartwright (2):
  drivers: of: implement reserved-memory handling for dma
  drivers: of: implement reserved-memory handling for cma

Marek Szyprowski (2):
  drivers: of: add initialization code for reserved memory
  ARM: init: add support for reserved memory defined by device tree

 .../bindings/reserved-memory/reserved-memory.txt   |  138 ++++++++++++
 arch/arm/mm/init.c                                 |    3 +
 drivers/of/Kconfig                                 |   20 ++
 drivers/of/Makefile                                |    3 +
 drivers/of/of_reserved_mem.c                       |  219 ++++++++++++++++++++
 drivers/of/of_reserved_mem_cma.c                   |   75 +++++++
 drivers/of/of_reserved_mem_dma.c                   |   78 +++++++
 drivers/of/platform.c                              |    7 +
 include/asm-generic/vmlinux.lds.h                  |   11 +
 include/linux/of_reserved_mem.h                    |   62 ++++++
 10 files changed, 616 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
 create mode 100644 drivers/of/of_reserved_mem.c
 create mode 100644 drivers/of/of_reserved_mem_cma.c
 create mode 100644 drivers/of/of_reserved_mem_dma.c
 create mode 100644 include/linux/of_reserved_mem.h

-- 
1.7.9.5

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

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
  2014-02-04 12:09 ` Marek Szyprowski
@ 2014-02-04 12:09   ` Marek Szyprowski
  -1 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-04 12:09 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linaro-mm-sig, devicetree, linux-doc
  Cc: Marek Szyprowski, Kyungmin Park, Benjamin Herrenschmidt,
	Arnd Bergmann, Michal Nazarewicz, Grant Likely, Tomasz Figa,
	Sascha Hauer, Laura Abbott, Rob Herring, Olof Johansson,
	Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
	Tomasz Figa, Kumar Gala, Nishanth Peethambaran, Marc,
	Josh Cartwright

This patch adds device tree support for contiguous and reserved memory
regions defined in device tree.

Large memory blocks can be reliably reserved only during early boot.
This must happen before the whole memory management subsystem is
initialized, because we need to ensure that the given contiguous blocks
are not yet allocated by kernel. Also it must happen before kernel
mappings for the whole low memory are created, to ensure that there will
be no mappings (for reserved blocks) or mapping with special properties
can be created (for CMA blocks). This all happens before device tree
structures are unflattened, so we need to get reserved memory layout
directly from fdt.

Later, those reserved memory regions are assigned to devices on each
device structure initialization.

Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Laura Abbott <lauraa@codeaurora.org>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
[joshc: rework to implement new DT binding, provide mechanism for
 plugging in new reserved-memory node handlers via
 RESERVEDMEM_OF_DECLARE]
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
[mszyprow: little code cleanup]
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/of/Kconfig                |    6 +
 drivers/of/Makefile               |    1 +
 drivers/of/of_reserved_mem.c      |  219 +++++++++++++++++++++++++++++++++++++
 drivers/of/platform.c             |    7 ++
 include/asm-generic/vmlinux.lds.h |   11 ++
 include/linux/of_reserved_mem.h   |   62 +++++++++++
 6 files changed, 306 insertions(+)
 create mode 100644 drivers/of/of_reserved_mem.c
 create mode 100644 include/linux/of_reserved_mem.h

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index c6973f101a3e..aba13df56f3a 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -75,4 +75,10 @@ config OF_MTD
 	depends on MTD
 	def_bool y
 
+config OF_RESERVED_MEM
+	depends on HAVE_MEMBLOCK
+	def_bool y
+	help
+	  Helpers to allow for reservation of memory regions
+
 endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index efd05102c405..ed9660adad77 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
 obj-$(CONFIG_OF_PCI)	+= of_pci.o
 obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
 obj-$(CONFIG_OF_MTD)	+= of_mtd.o
+obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
new file mode 100644
index 000000000000..f17cd56e68d9
--- /dev/null
+++ b/drivers/of/of_reserved_mem.c
@@ -0,0 +1,219 @@
+/*
+ * Device tree based initialization code for reserved memory.
+ *
+ * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ * Author: Josh Cartwright <joshc@codeaurora.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License or (at your optional) any later version of the license.
+ */
+#include <linux/memblock.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/mm.h>
+#include <linux/sizes.h>
+#include <linux/of_reserved_mem.h>
+
+#define MAX_RESERVED_REGIONS	16
+static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
+static int reserved_mem_count;
+
+int __init of_parse_flat_dt_reg(unsigned long node, const char *uname,
+				   phys_addr_t *base, phys_addr_t *size)
+{
+	unsigned long len;
+	__be32 *prop;
+
+	prop = of_get_flat_dt_prop(node, "reg", &len);
+	if (!prop)
+		return -EINVAL;
+
+	if (len < (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) {
+		pr_err("Reserved memory: invalid reg property in '%s' node.\n",
+				uname);
+		return -EINVAL;
+	}
+
+	*base = dt_mem_next_cell(dt_root_addr_cells, &prop);
+	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
+	return 0;
+}
+
+int __init of_parse_flat_dt_size(unsigned long node, const char *uname,
+				    phys_addr_t *size)
+{
+	unsigned long len;
+	__be32 *prop;
+
+	prop = of_get_flat_dt_prop(node, "size", &len);
+	if (!prop)
+		return -EINVAL;
+
+	if (len < dt_root_size_cells * sizeof(__be32)) {
+		pr_err("Reserved memory: invalid size property in '%s' node.\n",
+				uname);
+		return -EINVAL;
+	}
+
+	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
+	return 0;
+}
+
+static int __init rmem_default_early_setup(struct reserved_mem *rmem,
+					   unsigned long node,
+					   const char *uname)
+{
+	int err;
+
+	if (of_get_flat_dt_prop(node, "compatible", NULL))
+		return -EINVAL;
+
+	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
+	if (err)
+		return err;
+
+	if (of_get_flat_dt_prop(node, "no-map", NULL))
+		err = memblock_remove(rmem->base, rmem->size);
+	else
+		err = memblock_reserve(rmem->base, rmem->size);
+
+	if (err == 0)
+		pr_info("Reserved memory: found '%s', memory base %pa, size %ld MiB\n",
+			uname, &rmem->base, (unsigned long)rmem->size / SZ_1M);
+
+	return err;
+}
+
+static const struct of_device_id rmem_default_id
+	__used __section(__reservedmem_of_table_end) = {
+	.data		= rmem_default_early_setup,
+};
+
+static int __init fdt_scan_reserved_mem(unsigned long node, const char *uname,
+					int depth, void *data)
+{
+	struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
+	extern const struct of_device_id __reservedmem_of_table[];
+	const struct of_device_id *id;
+	const char *status;
+
+	if (reserved_mem_count == ARRAY_SIZE(reserved_mem)) {
+		pr_err("Reserved memory: not enough space all defined regions.\n");
+		return -ENOSPC;
+	}
+
+	status = of_get_flat_dt_prop(node, "status", NULL);
+	if (status && strcmp(status, "okay") != 0)
+		return 0;
+
+	/*
+	 * The default handler above ensures this section is terminated with a
+	 * id whose compatible string is empty
+	 */
+	for (id = __reservedmem_of_table; id <= &rmem_default_id; id++) {
+		reservedmem_of_init_fn initfn = id->data;
+		const char *compat = id->compatible;
+
+		if (compat[0] && !of_flat_dt_is_compatible(node, compat))
+			continue;
+
+		if (initfn(rmem, node, uname) == 0) {
+			pr_info("Reserved memory: created %s node, compatible id %s\n",
+				uname, compat);
+			rmem->name = uname;
+			reserved_mem_count++;
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static struct reserved_mem *find_rmem(struct device_node *np)
+{
+	const char *name;
+	unsigned int i;
+
+	name = kbasename(np->full_name);
+
+	for (i = 0; i < reserved_mem_count; i++)
+		if (strcmp(name, reserved_mem[i].name) == 0)
+			return &reserved_mem[i];
+
+	return NULL;
+}
+
+/**
+ * of_reserved_mem_device_init() - assign reserved memory region to given device
+ *
+ * This function assign memory region pointed by "memory-region" device tree
+ * property to the given device.
+ */
+void of_reserved_mem_device_init(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct reserved_mem *rmem;
+	struct of_phandle_args s;
+	unsigned int i;
+
+	for (i = 0; of_parse_phandle_with_args(np, "memory-region",
+				"#memory-region-cells", i, &s) == 0; i++) {
+
+		rmem = find_rmem(s.np);
+		if (!rmem || !rmem->ops || !rmem->ops->device_init) {
+			of_node_put(s.np);
+			continue;
+		}
+
+		rmem->ops->device_init(rmem, dev, &s);
+		dev_info(dev, "assigned reserved memory node %s\n",
+			 rmem->name);
+		of_node_put(s.np);
+		break;
+	}
+}
+
+/**
+ * of_reserved_mem_device_release() - release reserved memory device structures
+ *
+ * This function releases structures allocated for memory region handling for
+ * the given device.
+ */
+void of_reserved_mem_device_release(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct reserved_mem *rmem;
+	struct of_phandle_args s;
+	unsigned int i;
+
+	for (i = 0; of_parse_phandle_with_args(np, "memory-region",
+				"#memory-region-cells", i, &s) == 0; i++) {
+
+		rmem = find_rmem(s.np);
+		if (rmem && rmem->ops && rmem->ops->device_release)
+			rmem->ops->device_release(rmem, dev);
+
+		of_node_put(s.np);
+	}
+}
+
+/**
+ * early_init_dt_scan_reserved_mem() - create reserved memory regions
+ *
+ * This function grabs memory from early allocator for device exclusive use
+ * defined in device tree structures. It should be called by arch specific code
+ * once the early allocator (memblock) has been activated and all other
+ * subsystems have already allocated/reserved memory.
+ */
+void __init early_init_dt_scan_reserved_mem(void)
+{
+	of_scan_flat_dt_by_path("/reserved-memory", fdt_scan_reserved_mem,
+				NULL);
+}
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 404d1daebefa..3df0b1826e8b 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -21,6 +21,7 @@
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/of_reserved_mem.h>
 #include <linux/platform_device.h>
 
 const struct of_device_id of_default_bus_match_table[] = {
@@ -220,6 +221,8 @@ static struct platform_device *of_platform_device_create_pdata(
 	dev->dev.bus = &platform_bus_type;
 	dev->dev.platform_data = platform_data;
 
+	of_reserved_mem_device_init(&dev->dev);
+
 	/* We do not fill the DMA ops for platform devices by default.
 	 * This is currently the responsibility of the platform code
 	 * to do such, possibly using a device notifier
@@ -227,6 +230,7 @@ static struct platform_device *of_platform_device_create_pdata(
 
 	if (of_device_add(dev) != 0) {
 		platform_device_put(dev);
+		of_reserved_mem_device_release(&dev->dev);
 		return NULL;
 	}
 
@@ -282,6 +286,8 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
 	else
 		of_device_make_bus_id(&dev->dev);
 
+	of_reserved_mem_device_init(&dev->dev);
+
 	/* Allow the HW Peripheral ID to be overridden */
 	prop = of_get_property(node, "arm,primecell-periphid", NULL);
 	if (prop)
@@ -308,6 +314,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
 	return dev;
 
 err_free:
+	of_reserved_mem_device_release(&dev->dev);
 	amba_device_put(dev);
 	return NULL;
 }
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index bc2121fa9132..f10f64fcc815 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -167,6 +167,16 @@
 #define CLK_OF_TABLES()
 #endif
 
+#ifdef CONFIG_OF_RESERVED_MEM
+#define RESERVEDMEM_OF_TABLES()				\
+	. = ALIGN(8);					\
+	VMLINUX_SYMBOL(__reservedmem_of_table) = .;	\
+	*(__reservedmem_of_table)			\
+	*(__reservedmem_of_table_end)
+#else
+#define RESERVEDMEM_OF_TABLES()
+#endif
+
 #define KERNEL_DTB()							\
 	STRUCT_ALIGN();							\
 	VMLINUX_SYMBOL(__dtb_start) = .;				\
@@ -490,6 +500,7 @@
 	TRACE_SYSCALLS()						\
 	MEM_DISCARD(init.rodata)					\
 	CLK_OF_TABLES()							\
+	RESERVEDMEM_OF_TABLES()						\
 	CLKSRC_OF_TABLES()						\
 	KERNEL_DTB()							\
 	IRQCHIP_OF_MATCH_TABLE()
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
new file mode 100644
index 000000000000..41f43828e1db
--- /dev/null
+++ b/include/linux/of_reserved_mem.h
@@ -0,0 +1,62 @@
+#ifndef __OF_RESERVED_MEM_H
+#define __OF_RESERVED_MEM_H
+
+struct cma;
+struct platform_device;
+struct of_phandle_args;
+struct reserved_mem_ops;
+
+struct reserved_mem {
+	const char			*name;
+	const struct reserved_mem_ops	*ops;
+	phys_addr_t			base;
+	phys_addr_t			size;
+	void				*priv;
+};
+
+struct reserved_mem_ops {
+	void	(*device_init)(struct reserved_mem *rmem,
+			       struct device *dev,
+			       struct of_phandle_args *args);
+	void	(*device_release)(struct reserved_mem *rmem,
+				  struct device *dev);
+};
+
+typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem,
+				      unsigned long node, const char *uname);
+
+#ifdef CONFIG_OF_RESERVED_MEM
+void of_reserved_mem_device_init(struct device *dev);
+void of_reserved_mem_device_release(struct device *dev);
+void early_init_dt_scan_reserved_mem(void);
+
+int of_parse_flat_dt_reg(unsigned long node, const char *uname,
+			 phys_addr_t *base, phys_addr_t *size);
+int of_parse_flat_dt_size(unsigned long node, const char *uname,
+			  phys_addr_t *size);
+
+#define RESERVEDMEM_OF_DECLARE(name, compat, init)			\
+	static const struct of_device_id __reservedmem_of_table_##name	\
+		__used __section(__reservedmem_of_table)		\
+		 = { .compatible = compat,				\
+		     .data = (init == (reservedmem_of_init_fn)NULL) ?	\
+				init : init }
+
+#else
+static inline void of_reserved_mem_device_init(struct device *dev) { }
+
+static inline
+void of_reserved_mem_device_release(struct device *dev) { }
+
+static inline void early_init_dt_scan_reserved_mem(void) { }
+
+#define RESERVEDMEM_OF_DECLARE(name, compat, init)			\
+	static const struct of_device_id __reservedmem_of_table_##name	\
+		__attribute__((unused))					\
+		 = { .compatible = compat,				\
+		     .data = (init == (reservedmem_of_init_fn)NULL) ?	\
+				init : init }
+
+#endif
+
+#endif /* __OF_RESERVED_MEM_H */
-- 
1.7.9.5


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

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-04 12:09   ` Marek Szyprowski
  0 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-04 12:09 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds device tree support for contiguous and reserved memory
regions defined in device tree.

Large memory blocks can be reliably reserved only during early boot.
This must happen before the whole memory management subsystem is
initialized, because we need to ensure that the given contiguous blocks
are not yet allocated by kernel. Also it must happen before kernel
mappings for the whole low memory are created, to ensure that there will
be no mappings (for reserved blocks) or mapping with special properties
can be created (for CMA blocks). This all happens before device tree
structures are unflattened, so we need to get reserved memory layout
directly from fdt.

Later, those reserved memory regions are assigned to devices on each
device structure initialization.

Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Laura Abbott <lauraa@codeaurora.org>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
[joshc: rework to implement new DT binding, provide mechanism for
 plugging in new reserved-memory node handlers via
 RESERVEDMEM_OF_DECLARE]
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
[mszyprow: little code cleanup]
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/of/Kconfig                |    6 +
 drivers/of/Makefile               |    1 +
 drivers/of/of_reserved_mem.c      |  219 +++++++++++++++++++++++++++++++++++++
 drivers/of/platform.c             |    7 ++
 include/asm-generic/vmlinux.lds.h |   11 ++
 include/linux/of_reserved_mem.h   |   62 +++++++++++
 6 files changed, 306 insertions(+)
 create mode 100644 drivers/of/of_reserved_mem.c
 create mode 100644 include/linux/of_reserved_mem.h

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index c6973f101a3e..aba13df56f3a 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -75,4 +75,10 @@ config OF_MTD
 	depends on MTD
 	def_bool y
 
+config OF_RESERVED_MEM
+	depends on HAVE_MEMBLOCK
+	def_bool y
+	help
+	  Helpers to allow for reservation of memory regions
+
 endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index efd05102c405..ed9660adad77 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
 obj-$(CONFIG_OF_PCI)	+= of_pci.o
 obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
 obj-$(CONFIG_OF_MTD)	+= of_mtd.o
+obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
new file mode 100644
index 000000000000..f17cd56e68d9
--- /dev/null
+++ b/drivers/of/of_reserved_mem.c
@@ -0,0 +1,219 @@
+/*
+ * Device tree based initialization code for reserved memory.
+ *
+ * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ * Author: Josh Cartwright <joshc@codeaurora.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License or (at your optional) any later version of the license.
+ */
+#include <linux/memblock.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/mm.h>
+#include <linux/sizes.h>
+#include <linux/of_reserved_mem.h>
+
+#define MAX_RESERVED_REGIONS	16
+static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
+static int reserved_mem_count;
+
+int __init of_parse_flat_dt_reg(unsigned long node, const char *uname,
+				   phys_addr_t *base, phys_addr_t *size)
+{
+	unsigned long len;
+	__be32 *prop;
+
+	prop = of_get_flat_dt_prop(node, "reg", &len);
+	if (!prop)
+		return -EINVAL;
+
+	if (len < (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) {
+		pr_err("Reserved memory: invalid reg property in '%s' node.\n",
+				uname);
+		return -EINVAL;
+	}
+
+	*base = dt_mem_next_cell(dt_root_addr_cells, &prop);
+	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
+	return 0;
+}
+
+int __init of_parse_flat_dt_size(unsigned long node, const char *uname,
+				    phys_addr_t *size)
+{
+	unsigned long len;
+	__be32 *prop;
+
+	prop = of_get_flat_dt_prop(node, "size", &len);
+	if (!prop)
+		return -EINVAL;
+
+	if (len < dt_root_size_cells * sizeof(__be32)) {
+		pr_err("Reserved memory: invalid size property in '%s' node.\n",
+				uname);
+		return -EINVAL;
+	}
+
+	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
+	return 0;
+}
+
+static int __init rmem_default_early_setup(struct reserved_mem *rmem,
+					   unsigned long node,
+					   const char *uname)
+{
+	int err;
+
+	if (of_get_flat_dt_prop(node, "compatible", NULL))
+		return -EINVAL;
+
+	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
+	if (err)
+		return err;
+
+	if (of_get_flat_dt_prop(node, "no-map", NULL))
+		err = memblock_remove(rmem->base, rmem->size);
+	else
+		err = memblock_reserve(rmem->base, rmem->size);
+
+	if (err == 0)
+		pr_info("Reserved memory: found '%s', memory base %pa, size %ld MiB\n",
+			uname, &rmem->base, (unsigned long)rmem->size / SZ_1M);
+
+	return err;
+}
+
+static const struct of_device_id rmem_default_id
+	__used __section(__reservedmem_of_table_end) = {
+	.data		= rmem_default_early_setup,
+};
+
+static int __init fdt_scan_reserved_mem(unsigned long node, const char *uname,
+					int depth, void *data)
+{
+	struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
+	extern const struct of_device_id __reservedmem_of_table[];
+	const struct of_device_id *id;
+	const char *status;
+
+	if (reserved_mem_count == ARRAY_SIZE(reserved_mem)) {
+		pr_err("Reserved memory: not enough space all defined regions.\n");
+		return -ENOSPC;
+	}
+
+	status = of_get_flat_dt_prop(node, "status", NULL);
+	if (status && strcmp(status, "okay") != 0)
+		return 0;
+
+	/*
+	 * The default handler above ensures this section is terminated with a
+	 * id whose compatible string is empty
+	 */
+	for (id = __reservedmem_of_table; id <= &rmem_default_id; id++) {
+		reservedmem_of_init_fn initfn = id->data;
+		const char *compat = id->compatible;
+
+		if (compat[0] && !of_flat_dt_is_compatible(node, compat))
+			continue;
+
+		if (initfn(rmem, node, uname) == 0) {
+			pr_info("Reserved memory: created %s node, compatible id %s\n",
+				uname, compat);
+			rmem->name = uname;
+			reserved_mem_count++;
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static struct reserved_mem *find_rmem(struct device_node *np)
+{
+	const char *name;
+	unsigned int i;
+
+	name = kbasename(np->full_name);
+
+	for (i = 0; i < reserved_mem_count; i++)
+		if (strcmp(name, reserved_mem[i].name) == 0)
+			return &reserved_mem[i];
+
+	return NULL;
+}
+
+/**
+ * of_reserved_mem_device_init() - assign reserved memory region to given device
+ *
+ * This function assign memory region pointed by "memory-region" device tree
+ * property to the given device.
+ */
+void of_reserved_mem_device_init(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct reserved_mem *rmem;
+	struct of_phandle_args s;
+	unsigned int i;
+
+	for (i = 0; of_parse_phandle_with_args(np, "memory-region",
+				"#memory-region-cells", i, &s) == 0; i++) {
+
+		rmem = find_rmem(s.np);
+		if (!rmem || !rmem->ops || !rmem->ops->device_init) {
+			of_node_put(s.np);
+			continue;
+		}
+
+		rmem->ops->device_init(rmem, dev, &s);
+		dev_info(dev, "assigned reserved memory node %s\n",
+			 rmem->name);
+		of_node_put(s.np);
+		break;
+	}
+}
+
+/**
+ * of_reserved_mem_device_release() - release reserved memory device structures
+ *
+ * This function releases structures allocated for memory region handling for
+ * the given device.
+ */
+void of_reserved_mem_device_release(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct reserved_mem *rmem;
+	struct of_phandle_args s;
+	unsigned int i;
+
+	for (i = 0; of_parse_phandle_with_args(np, "memory-region",
+				"#memory-region-cells", i, &s) == 0; i++) {
+
+		rmem = find_rmem(s.np);
+		if (rmem && rmem->ops && rmem->ops->device_release)
+			rmem->ops->device_release(rmem, dev);
+
+		of_node_put(s.np);
+	}
+}
+
+/**
+ * early_init_dt_scan_reserved_mem() - create reserved memory regions
+ *
+ * This function grabs memory from early allocator for device exclusive use
+ * defined in device tree structures. It should be called by arch specific code
+ * once the early allocator (memblock) has been activated and all other
+ * subsystems have already allocated/reserved memory.
+ */
+void __init early_init_dt_scan_reserved_mem(void)
+{
+	of_scan_flat_dt_by_path("/reserved-memory", fdt_scan_reserved_mem,
+				NULL);
+}
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 404d1daebefa..3df0b1826e8b 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -21,6 +21,7 @@
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/of_reserved_mem.h>
 #include <linux/platform_device.h>
 
 const struct of_device_id of_default_bus_match_table[] = {
@@ -220,6 +221,8 @@ static struct platform_device *of_platform_device_create_pdata(
 	dev->dev.bus = &platform_bus_type;
 	dev->dev.platform_data = platform_data;
 
+	of_reserved_mem_device_init(&dev->dev);
+
 	/* We do not fill the DMA ops for platform devices by default.
 	 * This is currently the responsibility of the platform code
 	 * to do such, possibly using a device notifier
@@ -227,6 +230,7 @@ static struct platform_device *of_platform_device_create_pdata(
 
 	if (of_device_add(dev) != 0) {
 		platform_device_put(dev);
+		of_reserved_mem_device_release(&dev->dev);
 		return NULL;
 	}
 
@@ -282,6 +286,8 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
 	else
 		of_device_make_bus_id(&dev->dev);
 
+	of_reserved_mem_device_init(&dev->dev);
+
 	/* Allow the HW Peripheral ID to be overridden */
 	prop = of_get_property(node, "arm,primecell-periphid", NULL);
 	if (prop)
@@ -308,6 +314,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
 	return dev;
 
 err_free:
+	of_reserved_mem_device_release(&dev->dev);
 	amba_device_put(dev);
 	return NULL;
 }
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index bc2121fa9132..f10f64fcc815 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -167,6 +167,16 @@
 #define CLK_OF_TABLES()
 #endif
 
+#ifdef CONFIG_OF_RESERVED_MEM
+#define RESERVEDMEM_OF_TABLES()				\
+	. = ALIGN(8);					\
+	VMLINUX_SYMBOL(__reservedmem_of_table) = .;	\
+	*(__reservedmem_of_table)			\
+	*(__reservedmem_of_table_end)
+#else
+#define RESERVEDMEM_OF_TABLES()
+#endif
+
 #define KERNEL_DTB()							\
 	STRUCT_ALIGN();							\
 	VMLINUX_SYMBOL(__dtb_start) = .;				\
@@ -490,6 +500,7 @@
 	TRACE_SYSCALLS()						\
 	MEM_DISCARD(init.rodata)					\
 	CLK_OF_TABLES()							\
+	RESERVEDMEM_OF_TABLES()						\
 	CLKSRC_OF_TABLES()						\
 	KERNEL_DTB()							\
 	IRQCHIP_OF_MATCH_TABLE()
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
new file mode 100644
index 000000000000..41f43828e1db
--- /dev/null
+++ b/include/linux/of_reserved_mem.h
@@ -0,0 +1,62 @@
+#ifndef __OF_RESERVED_MEM_H
+#define __OF_RESERVED_MEM_H
+
+struct cma;
+struct platform_device;
+struct of_phandle_args;
+struct reserved_mem_ops;
+
+struct reserved_mem {
+	const char			*name;
+	const struct reserved_mem_ops	*ops;
+	phys_addr_t			base;
+	phys_addr_t			size;
+	void				*priv;
+};
+
+struct reserved_mem_ops {
+	void	(*device_init)(struct reserved_mem *rmem,
+			       struct device *dev,
+			       struct of_phandle_args *args);
+	void	(*device_release)(struct reserved_mem *rmem,
+				  struct device *dev);
+};
+
+typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem,
+				      unsigned long node, const char *uname);
+
+#ifdef CONFIG_OF_RESERVED_MEM
+void of_reserved_mem_device_init(struct device *dev);
+void of_reserved_mem_device_release(struct device *dev);
+void early_init_dt_scan_reserved_mem(void);
+
+int of_parse_flat_dt_reg(unsigned long node, const char *uname,
+			 phys_addr_t *base, phys_addr_t *size);
+int of_parse_flat_dt_size(unsigned long node, const char *uname,
+			  phys_addr_t *size);
+
+#define RESERVEDMEM_OF_DECLARE(name, compat, init)			\
+	static const struct of_device_id __reservedmem_of_table_##name	\
+		__used __section(__reservedmem_of_table)		\
+		 = { .compatible = compat,				\
+		     .data = (init == (reservedmem_of_init_fn)NULL) ?	\
+				init : init }
+
+#else
+static inline void of_reserved_mem_device_init(struct device *dev) { }
+
+static inline
+void of_reserved_mem_device_release(struct device *dev) { }
+
+static inline void early_init_dt_scan_reserved_mem(void) { }
+
+#define RESERVEDMEM_OF_DECLARE(name, compat, init)			\
+	static const struct of_device_id __reservedmem_of_table_##name	\
+		__attribute__((unused))					\
+		 = { .compatible = compat,				\
+		     .data = (init == (reservedmem_of_init_fn)NULL) ?	\
+				init : init }
+
+#endif
+
+#endif /* __OF_RESERVED_MEM_H */
-- 
1.7.9.5

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

* [PATCH v2 2/5] drivers: of: implement reserved-memory handling for dma
  2014-02-04 12:09 ` Marek Szyprowski
  (?)
@ 2014-02-04 12:09   ` Marek Szyprowski
  -1 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-04 12:09 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linaro-mm-sig, devicetree, linux-doc
  Cc: Marek Szyprowski, Kyungmin Park, Benjamin Herrenschmidt,
	Arnd Bergmann, Michal Nazarewicz, Grant Likely, Tomasz Figa,
	Sascha Hauer, Laura Abbott, Rob Herring, Olof Johansson,
	Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
	Tomasz Figa, Kumar Gala, Nishanth Peethambaran, Marc,
	Josh Cartwright

From: Josh Cartwright <joshc@codeaurora.org>

Add support for handling 'shared-dma-pool' reserved-memory nodes using
dma exclusive driver (dma_alloc_coherent()).

Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Laura Abbott <lauraa@codeaurora.org>
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/of/Kconfig               |    7 ++++
 drivers/of/Makefile              |    1 +
 drivers/of/of_reserved_mem_dma.c |   78 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 86 insertions(+)
 create mode 100644 drivers/of/of_reserved_mem_dma.c

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index aba13df56f3a..7ac330473ec9 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -81,4 +81,11 @@ config OF_RESERVED_MEM
 	help
 	  Helpers to allow for reservation of memory regions
 
+config OF_RESERVED_MEM_DMA
+	depends on OF_RESERVED_MEM
+	depends on HAVE_GENERIC_DMA_COHERENT
+	def_bool y
+	help
+	  Helpers for reserving memory regions for DMA use
+
 endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index ed9660adad77..6142227ca854 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_OF_PCI)	+= of_pci.o
 obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
 obj-$(CONFIG_OF_MTD)	+= of_mtd.o
 obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
+obj-$(CONFIG_OF_RESERVED_MEM_DMA) += of_reserved_mem_dma.o
diff --git a/drivers/of/of_reserved_mem_dma.c b/drivers/of/of_reserved_mem_dma.c
new file mode 100644
index 000000000000..53a4cac6084a
--- /dev/null
+++ b/drivers/of/of_reserved_mem_dma.c
@@ -0,0 +1,78 @@
+/*
+ * Device tree based initialization code for DMA reserved regions.
+ *
+ * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ * Author: Josh Cartwright <joshc@codeaurora.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License or (at your optional) any later version of the license.
+ */
+#include <linux/memblock.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/mm.h>
+#include <linux/sizes.h>
+#include <linux/mm_types.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_reserved_mem.h>
+
+static void rmem_dma_device_init(struct reserved_mem *rmem,
+				 struct device *dev,
+				 struct of_phandle_args *args)
+{
+	dma_declare_coherent_memory(dev, rmem->base, rmem->base,
+		rmem->size, DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+}
+
+static void rmem_dma_device_release(struct reserved_mem *rmem,
+				    struct device *dev)
+{
+	dma_release_declared_memory(dev);
+}
+
+static const struct reserved_mem_ops rmem_dma_ops = {
+	.device_init	= rmem_dma_device_init,
+	.device_release	= rmem_dma_device_release,
+};
+
+static int __init rmem_dma_setup(struct reserved_mem *rmem,
+				 unsigned long node,
+				 const char *uname)
+{
+	int err;
+
+	if (of_get_flat_dt_prop(node, "reusable", NULL))
+		return -EINVAL;
+
+	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
+	if (!err)
+		goto out_done;
+
+	err = of_parse_flat_dt_size(node, uname, &rmem->size);
+	if (err)
+		goto out_err;
+
+	rmem->base = memblock_alloc_base(rmem->size, PAGE_SIZE,
+					 MEMBLOCK_ALLOC_ANYWHERE);
+	memblock_free(rmem->base, rmem->size);
+
+out_done:
+	rmem->ops = &rmem_dma_ops;
+	pr_info("Reserved memory: created DMA memory pool at %pa, size %ld MiB\n",
+		&rmem->base, (unsigned long)rmem->size / SZ_1M);
+
+	return memblock_remove(rmem->base, rmem->size);
+
+out_err:
+	pr_err("Reserved memory: unable to setup '%s' memory region for DMA.\n",
+	       uname);
+	return err;
+}
+RESERVEDMEM_OF_DECLARE(dma, "shared-dma-pool", rmem_dma_setup);
-- 
1.7.9.5


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

* [PATCH v2 2/5] drivers: of: implement reserved-memory handling for dma
@ 2014-02-04 12:09   ` Marek Szyprowski
  0 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-04 12:09 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linaro-mm-sig, devicetree, linux-doc
  Cc: Mark Rutland, Laura Abbott, Pawel Moll, Arnd Bergmann,
	Stephen Warren, Josh Cartwright, Benjamin Herrenschmidt,
	Tomasz Figa, Olof Johansson, Tomasz Figa, Michal Nazarewicz,
	Rob Herring, Kyungmin Park, Kumar Gala, Grant Likely,
	Ian Campbell, Nishanth Peethambaran, Sascha Hauer, Marc,
	Marek Szyprowski

From: Josh Cartwright <joshc@codeaurora.org>

Add support for handling 'shared-dma-pool' reserved-memory nodes using
dma exclusive driver (dma_alloc_coherent()).

Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Laura Abbott <lauraa@codeaurora.org>
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/of/Kconfig               |    7 ++++
 drivers/of/Makefile              |    1 +
 drivers/of/of_reserved_mem_dma.c |   78 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 86 insertions(+)
 create mode 100644 drivers/of/of_reserved_mem_dma.c

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index aba13df56f3a..7ac330473ec9 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -81,4 +81,11 @@ config OF_RESERVED_MEM
 	help
 	  Helpers to allow for reservation of memory regions
 
+config OF_RESERVED_MEM_DMA
+	depends on OF_RESERVED_MEM
+	depends on HAVE_GENERIC_DMA_COHERENT
+	def_bool y
+	help
+	  Helpers for reserving memory regions for DMA use
+
 endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index ed9660adad77..6142227ca854 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_OF_PCI)	+= of_pci.o
 obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
 obj-$(CONFIG_OF_MTD)	+= of_mtd.o
 obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
+obj-$(CONFIG_OF_RESERVED_MEM_DMA) += of_reserved_mem_dma.o
diff --git a/drivers/of/of_reserved_mem_dma.c b/drivers/of/of_reserved_mem_dma.c
new file mode 100644
index 000000000000..53a4cac6084a
--- /dev/null
+++ b/drivers/of/of_reserved_mem_dma.c
@@ -0,0 +1,78 @@
+/*
+ * Device tree based initialization code for DMA reserved regions.
+ *
+ * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ * Author: Josh Cartwright <joshc@codeaurora.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License or (at your optional) any later version of the license.
+ */
+#include <linux/memblock.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/mm.h>
+#include <linux/sizes.h>
+#include <linux/mm_types.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_reserved_mem.h>
+
+static void rmem_dma_device_init(struct reserved_mem *rmem,
+				 struct device *dev,
+				 struct of_phandle_args *args)
+{
+	dma_declare_coherent_memory(dev, rmem->base, rmem->base,
+		rmem->size, DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+}
+
+static void rmem_dma_device_release(struct reserved_mem *rmem,
+				    struct device *dev)
+{
+	dma_release_declared_memory(dev);
+}
+
+static const struct reserved_mem_ops rmem_dma_ops = {
+	.device_init	= rmem_dma_device_init,
+	.device_release	= rmem_dma_device_release,
+};
+
+static int __init rmem_dma_setup(struct reserved_mem *rmem,
+				 unsigned long node,
+				 const char *uname)
+{
+	int err;
+
+	if (of_get_flat_dt_prop(node, "reusable", NULL))
+		return -EINVAL;
+
+	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
+	if (!err)
+		goto out_done;
+
+	err = of_parse_flat_dt_size(node, uname, &rmem->size);
+	if (err)
+		goto out_err;
+
+	rmem->base = memblock_alloc_base(rmem->size, PAGE_SIZE,
+					 MEMBLOCK_ALLOC_ANYWHERE);
+	memblock_free(rmem->base, rmem->size);
+
+out_done:
+	rmem->ops = &rmem_dma_ops;
+	pr_info("Reserved memory: created DMA memory pool at %pa, size %ld MiB\n",
+		&rmem->base, (unsigned long)rmem->size / SZ_1M);
+
+	return memblock_remove(rmem->base, rmem->size);
+
+out_err:
+	pr_err("Reserved memory: unable to setup '%s' memory region for DMA.\n",
+	       uname);
+	return err;
+}
+RESERVEDMEM_OF_DECLARE(dma, "shared-dma-pool", rmem_dma_setup);
-- 
1.7.9.5

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

* [PATCH v2 2/5] drivers: of: implement reserved-memory handling for dma
@ 2014-02-04 12:09   ` Marek Szyprowski
  0 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-04 12:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Josh Cartwright <joshc@codeaurora.org>

Add support for handling 'shared-dma-pool' reserved-memory nodes using
dma exclusive driver (dma_alloc_coherent()).

Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Laura Abbott <lauraa@codeaurora.org>
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/of/Kconfig               |    7 ++++
 drivers/of/Makefile              |    1 +
 drivers/of/of_reserved_mem_dma.c |   78 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 86 insertions(+)
 create mode 100644 drivers/of/of_reserved_mem_dma.c

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index aba13df56f3a..7ac330473ec9 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -81,4 +81,11 @@ config OF_RESERVED_MEM
 	help
 	  Helpers to allow for reservation of memory regions
 
+config OF_RESERVED_MEM_DMA
+	depends on OF_RESERVED_MEM
+	depends on HAVE_GENERIC_DMA_COHERENT
+	def_bool y
+	help
+	  Helpers for reserving memory regions for DMA use
+
 endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index ed9660adad77..6142227ca854 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_OF_PCI)	+= of_pci.o
 obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
 obj-$(CONFIG_OF_MTD)	+= of_mtd.o
 obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
+obj-$(CONFIG_OF_RESERVED_MEM_DMA) += of_reserved_mem_dma.o
diff --git a/drivers/of/of_reserved_mem_dma.c b/drivers/of/of_reserved_mem_dma.c
new file mode 100644
index 000000000000..53a4cac6084a
--- /dev/null
+++ b/drivers/of/of_reserved_mem_dma.c
@@ -0,0 +1,78 @@
+/*
+ * Device tree based initialization code for DMA reserved regions.
+ *
+ * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ * Author: Josh Cartwright <joshc@codeaurora.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License or (at your optional) any later version of the license.
+ */
+#include <linux/memblock.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/mm.h>
+#include <linux/sizes.h>
+#include <linux/mm_types.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_reserved_mem.h>
+
+static void rmem_dma_device_init(struct reserved_mem *rmem,
+				 struct device *dev,
+				 struct of_phandle_args *args)
+{
+	dma_declare_coherent_memory(dev, rmem->base, rmem->base,
+		rmem->size, DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+}
+
+static void rmem_dma_device_release(struct reserved_mem *rmem,
+				    struct device *dev)
+{
+	dma_release_declared_memory(dev);
+}
+
+static const struct reserved_mem_ops rmem_dma_ops = {
+	.device_init	= rmem_dma_device_init,
+	.device_release	= rmem_dma_device_release,
+};
+
+static int __init rmem_dma_setup(struct reserved_mem *rmem,
+				 unsigned long node,
+				 const char *uname)
+{
+	int err;
+
+	if (of_get_flat_dt_prop(node, "reusable", NULL))
+		return -EINVAL;
+
+	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
+	if (!err)
+		goto out_done;
+
+	err = of_parse_flat_dt_size(node, uname, &rmem->size);
+	if (err)
+		goto out_err;
+
+	rmem->base = memblock_alloc_base(rmem->size, PAGE_SIZE,
+					 MEMBLOCK_ALLOC_ANYWHERE);
+	memblock_free(rmem->base, rmem->size);
+
+out_done:
+	rmem->ops = &rmem_dma_ops;
+	pr_info("Reserved memory: created DMA memory pool at %pa, size %ld MiB\n",
+		&rmem->base, (unsigned long)rmem->size / SZ_1M);
+
+	return memblock_remove(rmem->base, rmem->size);
+
+out_err:
+	pr_err("Reserved memory: unable to setup '%s' memory region for DMA.\n",
+	       uname);
+	return err;
+}
+RESERVEDMEM_OF_DECLARE(dma, "shared-dma-pool", rmem_dma_setup);
-- 
1.7.9.5

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

* [PATCH v2 3/5] drivers: of: implement reserved-memory handling for cma
  2014-02-04 12:09 ` Marek Szyprowski
@ 2014-02-04 12:09   ` Marek Szyprowski
  -1 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-04 12:09 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linaro-mm-sig, devicetree, linux-doc
  Cc: Marek Szyprowski, Kyungmin Park, Benjamin Herrenschmidt,
	Arnd Bergmann, Michal Nazarewicz, Grant Likely, Tomasz Figa,
	Sascha Hauer, Laura Abbott, Rob Herring, Olof Johansson,
	Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
	Tomasz Figa, Kumar Gala, Nishanth Peethambaran, Marc,
	Josh Cartwright

From: Josh Cartwright <joshc@codeaurora.org>

Add support for handling 'shared-dma-pool' reserved-memory nodes using
Contiguous Memory Allocator driver.

Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Laura Abbott <lauraa@codeaurora.org>
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/of/Kconfig               |    7 ++++
 drivers/of/Makefile              |    1 +
 drivers/of/of_reserved_mem_cma.c |   75 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 83 insertions(+)
 create mode 100644 drivers/of/of_reserved_mem_cma.c

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 7ac330473ec9..5dd3a80910d2 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -81,6 +81,13 @@ config OF_RESERVED_MEM
 	help
 	  Helpers to allow for reservation of memory regions
 
+config OF_RESERVED_MEM_CMA
+	depends on OF_RESERVED_MEM
+	depends on DMA_CMA
+	def_bool y
+	help
+	  Helpers for reserving memory regions for DMA use
+
 config OF_RESERVED_MEM_DMA
 	depends on OF_RESERVED_MEM
 	depends on HAVE_GENERIC_DMA_COHERENT
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 6142227ca854..49b9078637b8 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -10,4 +10,5 @@ obj-$(CONFIG_OF_PCI)	+= of_pci.o
 obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
 obj-$(CONFIG_OF_MTD)	+= of_mtd.o
 obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
+obj-$(CONFIG_OF_RESERVED_MEM_CMA) += of_reserved_mem_cma.o
 obj-$(CONFIG_OF_RESERVED_MEM_DMA) += of_reserved_mem_dma.o
diff --git a/drivers/of/of_reserved_mem_cma.c b/drivers/of/of_reserved_mem_cma.c
new file mode 100644
index 000000000000..601d80655102
--- /dev/null
+++ b/drivers/of/of_reserved_mem_cma.c
@@ -0,0 +1,75 @@
+/*
+ * Device tree based initialization code for DMA reserved regions.
+ *
+ * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ * Author: Josh Cartwright <joshc@codeaurora.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License or (at your optional) any later version of the license.
+ */
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/mm.h>
+#include <linux/sizes.h>
+#include <linux/mm_types.h>
+#include <linux/dma-contiguous.h>
+#include <linux/of_reserved_mem.h>
+
+static void rmem_cma_device_init(struct reserved_mem *rmem,
+				 struct device *dev,
+				 struct of_phandle_args *args)
+{
+	struct cma *cma = rmem->priv;
+	dev_set_cma_area(dev, cma);
+}
+
+static const struct reserved_mem_ops rmem_cma_ops = {
+	.device_init	= rmem_cma_device_init,
+};
+
+static int __init rmem_cma_setup(struct reserved_mem *rmem,
+				 unsigned long node,
+				 const char *uname)
+{
+	struct cma *cma;
+	int err;
+
+	if (!of_get_flat_dt_prop(node, "reusable", NULL))
+		return -EINVAL;
+
+	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
+	if (!err)
+		goto out_done;
+
+	rmem->base = 0;
+	err = of_parse_flat_dt_size(node, uname, &rmem->size);
+	if (err)
+		goto out_err;
+
+out_done:
+	err = dma_contiguous_reserve_area(rmem->size, rmem->base, 0,
+					  &cma);
+	if (err) {
+		pr_err("Reserved memory: unable to setup CMA region\n");
+		return err;
+	}
+
+	if (of_get_flat_dt_prop(node, "linux,cma-default", NULL))
+		dma_contiguous_set_default(cma);
+
+	rmem->ops = &rmem_cma_ops;
+	rmem->priv = cma;
+
+	return 0;
+out_err:
+	pr_err("Reseved memory: malformed node '%s'.\n", uname);
+	return err;
+}
+RESERVEDMEM_OF_DECLARE(cma, "shared-dma-pool", rmem_cma_setup);
-- 
1.7.9.5


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

* [PATCH v2 3/5] drivers: of: implement reserved-memory handling for cma
@ 2014-02-04 12:09   ` Marek Szyprowski
  0 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-04 12:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Josh Cartwright <joshc@codeaurora.org>

Add support for handling 'shared-dma-pool' reserved-memory nodes using
Contiguous Memory Allocator driver.

Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Laura Abbott <lauraa@codeaurora.org>
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/of/Kconfig               |    7 ++++
 drivers/of/Makefile              |    1 +
 drivers/of/of_reserved_mem_cma.c |   75 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 83 insertions(+)
 create mode 100644 drivers/of/of_reserved_mem_cma.c

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 7ac330473ec9..5dd3a80910d2 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -81,6 +81,13 @@ config OF_RESERVED_MEM
 	help
 	  Helpers to allow for reservation of memory regions
 
+config OF_RESERVED_MEM_CMA
+	depends on OF_RESERVED_MEM
+	depends on DMA_CMA
+	def_bool y
+	help
+	  Helpers for reserving memory regions for DMA use
+
 config OF_RESERVED_MEM_DMA
 	depends on OF_RESERVED_MEM
 	depends on HAVE_GENERIC_DMA_COHERENT
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 6142227ca854..49b9078637b8 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -10,4 +10,5 @@ obj-$(CONFIG_OF_PCI)	+= of_pci.o
 obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
 obj-$(CONFIG_OF_MTD)	+= of_mtd.o
 obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
+obj-$(CONFIG_OF_RESERVED_MEM_CMA) += of_reserved_mem_cma.o
 obj-$(CONFIG_OF_RESERVED_MEM_DMA) += of_reserved_mem_dma.o
diff --git a/drivers/of/of_reserved_mem_cma.c b/drivers/of/of_reserved_mem_cma.c
new file mode 100644
index 000000000000..601d80655102
--- /dev/null
+++ b/drivers/of/of_reserved_mem_cma.c
@@ -0,0 +1,75 @@
+/*
+ * Device tree based initialization code for DMA reserved regions.
+ *
+ * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ * Author: Josh Cartwright <joshc@codeaurora.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License or (at your optional) any later version of the license.
+ */
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/mm.h>
+#include <linux/sizes.h>
+#include <linux/mm_types.h>
+#include <linux/dma-contiguous.h>
+#include <linux/of_reserved_mem.h>
+
+static void rmem_cma_device_init(struct reserved_mem *rmem,
+				 struct device *dev,
+				 struct of_phandle_args *args)
+{
+	struct cma *cma = rmem->priv;
+	dev_set_cma_area(dev, cma);
+}
+
+static const struct reserved_mem_ops rmem_cma_ops = {
+	.device_init	= rmem_cma_device_init,
+};
+
+static int __init rmem_cma_setup(struct reserved_mem *rmem,
+				 unsigned long node,
+				 const char *uname)
+{
+	struct cma *cma;
+	int err;
+
+	if (!of_get_flat_dt_prop(node, "reusable", NULL))
+		return -EINVAL;
+
+	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
+	if (!err)
+		goto out_done;
+
+	rmem->base = 0;
+	err = of_parse_flat_dt_size(node, uname, &rmem->size);
+	if (err)
+		goto out_err;
+
+out_done:
+	err = dma_contiguous_reserve_area(rmem->size, rmem->base, 0,
+					  &cma);
+	if (err) {
+		pr_err("Reserved memory: unable to setup CMA region\n");
+		return err;
+	}
+
+	if (of_get_flat_dt_prop(node, "linux,cma-default", NULL))
+		dma_contiguous_set_default(cma);
+
+	rmem->ops = &rmem_cma_ops;
+	rmem->priv = cma;
+
+	return 0;
+out_err:
+	pr_err("Reseved memory: malformed node '%s'.\n", uname);
+	return err;
+}
+RESERVEDMEM_OF_DECLARE(cma, "shared-dma-pool", rmem_cma_setup);
-- 
1.7.9.5

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

* [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
  2014-02-04 12:09 ` Marek Szyprowski
@ 2014-02-04 12:09   ` Marek Szyprowski
  -1 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-04 12:09 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linaro-mm-sig, devicetree, linux-doc
  Cc: Marek Szyprowski, Kyungmin Park, Benjamin Herrenschmidt,
	Arnd Bergmann, Michal Nazarewicz, Grant Likely, Tomasz Figa,
	Sascha Hauer, Laura Abbott, Rob Herring, Olof Johansson,
	Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
	Tomasz Figa, Kumar Gala, Nishanth Peethambaran, Marc,
	Josh Cartwright

Enable reserved memory initialization from device tree.

Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Laura Abbott <lauraa@codeaurora.org>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mm/init.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 804d61566a53..ebafdb479410 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -17,6 +17,7 @@
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
 #include <linux/of_fdt.h>
+#include <linux/of_reserved_mem.h>
 #include <linux/highmem.h>
 #include <linux/gfp.h>
 #include <linux/memblock.h>
@@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
 	if (mdesc->reserve)
 		mdesc->reserve();
 
+	early_init_dt_scan_reserved_mem();
+
 	/*
 	 * reserve memory for DMA contigouos allocations,
 	 * must come from DMA area inside low memory
-- 
1.7.9.5


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

* [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
@ 2014-02-04 12:09   ` Marek Szyprowski
  0 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-04 12:09 UTC (permalink / raw)
  To: linux-arm-kernel

Enable reserved memory initialization from device tree.

Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Laura Abbott <lauraa@codeaurora.org>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mm/init.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 804d61566a53..ebafdb479410 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -17,6 +17,7 @@
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
 #include <linux/of_fdt.h>
+#include <linux/of_reserved_mem.h>
 #include <linux/highmem.h>
 #include <linux/gfp.h>
 #include <linux/memblock.h>
@@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
 	if (mdesc->reserve)
 		mdesc->reserve();
 
+	early_init_dt_scan_reserved_mem();
+
 	/*
 	 * reserve memory for DMA contigouos allocations,
 	 * must come from DMA area inside low memory
-- 
1.7.9.5

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

* [PATCH v2 5/5] of: document bindings for reserved-memory nodes
  2014-02-04 12:09 ` Marek Szyprowski
@ 2014-02-04 12:09   ` Marek Szyprowski
  -1 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-04 12:09 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linaro-mm-sig, devicetree, linux-doc
  Cc: Marek Szyprowski, Kyungmin Park, Benjamin Herrenschmidt,
	Arnd Bergmann, Michal Nazarewicz, Grant Likely, Tomasz Figa,
	Sascha Hauer, Laura Abbott, Rob Herring, Olof Johansson,
	Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
	Tomasz Figa, Kumar Gala, Nishanth Peethambaran, Marc,
	Josh Cartwright

From: Grant Likely <grant.likely@linaro.org>

Reserved memory nodes allow for the reservation of static (fixed
address) regions, or dynamically allocated regions for a specific
purpose.

[joshc: Based on binding document proposed (in non-patch form) here:
 http://lkml.kernel.org/g/20131030134702.19B57C402A0@trevor.secretlab.ca
 adapted to support #memory-region-cells]

Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Laura Abbott <lauraa@codeaurora.org>
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 .../bindings/reserved-memory/reserved-memory.txt   |  138 ++++++++++++++++++++
 1 file changed, 138 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt

diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
new file mode 100644
index 000000000000..a606ce90c9c4
--- /dev/null
+++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
@@ -0,0 +1,138 @@
+*** Reserved memory regions ***
+
+Reserved memory is specified as a node under the /reserved-memory node.
+The operating system shall exclude reserved memory from normal usage
+one can create child nodes describing particular reserved (excluded from
+normal use) memory regions. Such memory regions are usually designed for
+the special usage by various device drivers.
+
+Parameters for each memory region can be encoded into the device tree
+with the following nodes:
+
+/reserved-memory node
+---------------------
+#address-cells, #size-cells (required) - standard definition
+    - Should use the same values as the root node
+#memory-region-cells (required) - dictates number of cells used in the child
+                                  nodes memory-region specifier
+ranges (required) - standard definition
+    - Should be empty
+
+/reserved-memory/ child nodes
+-----------------------------
+Each child of the reserved-memory node specifies one or more regions of
+reserved memory. Each child node may either use a 'reg' property to
+specify a specific range of reserved memory, or a 'size' property with
+optional constraints to request a dynamically allocated block of memory.
+
+Following the generic-names recommended practice, node names should
+reflect the purpose of the node (ie. "framebuffer" or "dma-pool"). Unit
+address (@<address>) should be appended to the name if the node is a
+static allocation.
+
+Properties:
+Requires either a) or b) below.
+a) static allocation
+   reg (required) - standard definition
+b) dynamic allocation
+   size (required) - length based on parent's #size-cells
+                   - Size in bytes of memory to reserve.
+   alignment (optional) - length based on parent's #size-cells
+                        - Address boundary for alignment of allocation.
+   alloc-ranges (optional) - prop-encoded-array (address, length pairs).
+                           - Specifies regions of memory that are
+                             acceptable to allocate from.
+
+If both reg and size are present, then the reg property takes precedence
+and size is ignored.
+
+Additional properties:
+compatible (optional) - standard definition
+    - may contain the following strings:
+        - shared-dma-pool: This indicates a region of memory meant to be
+          used as a shared pool of DMA buffers for a set of devices. It can
+          be used by an operating system to instanciate the necessary pool
+          management subsystem if necessary.
+        - vendor specific string in the form <vendor>,[<device>-]<usage>
+no-map (optional) - empty property
+    - Indicates the operating system must not create a virtual mapping
+      of the region as part of its standard mapping of system memory,
+      nor permit speculative access to it under any circumstances other
+      than under the control of the device driver using the region.
+reusable (optional) - empty property
+    - The operating system can use the memory in this region with the
+      limitation that the device driver(s) owning the region need to be
+      able to reclaim it back. Typically that means that the operating
+      system can use that region to store volatile or cached data that
+      can be otherwise regenerated or migrated elsewhere.
+
+Linux implementation note:
+- If a "linux,cma-default" property is present, then Linux will use the
+  region for the default pool of the contiguous memory allocator.
+
+Device node references to reserved memory
+-----------------------------------------
+Regions in the /reserved-memory node may be referenced by other device
+nodes by adding a memory-region property to the device node.
+
+memory-region (optional) - phandle, specifier pairs to children of /reserved-memory
+
+Example
+-------
+This example defines 3 contiguous regions are defined for Linux kernel:
+one default of all device drivers (named linux,cma@72000000 and 64MiB in size),
+one dedicated to the framebuffer device (named framebuffer@78000000, 8MiB), and
+one for multimedia processing (named multimedia-memory@77000000, 64MiB).
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	memory {
+		reg = <0x40000000 0x40000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		/* global autoconfigured region for contiguous allocations */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			#memory-region-cells = <0>;
+			size = <0x4000000>;
+			alignment = <0x2000>;
+			linux,cma-default;
+		};
+
+		display_reserved: framebuffer@78000000 {
+			#memory-region-cells = <0>;
+			reg = <0x78000000 0x800000>;
+		};
+
+		multimedia_reserved: multimedia@77000000 {
+			compatible = "acme,multimedia-memory";
+			#memory-region-cells = <1>;
+			reg = <0x77000000 0x4000000>;
+		};
+	};
+
+	/* ... */
+
+	fb0: video@12300000 {
+		memory-region = <&display_reserved>;
+		/* ... */
+	};
+
+	scaler: scaler@12500000 {
+		memory-region = <&multimedia_reserved 0xdeadbeef>;
+		/* ... */
+	};
+
+	codec: codec@12600000 {
+		memory-region = <&multimedia_reserved 0xfeebdaed>;
+		/* ... */
+	};
+};
-- 
1.7.9.5


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

* [PATCH v2 5/5] of: document bindings for reserved-memory nodes
@ 2014-02-04 12:09   ` Marek Szyprowski
  0 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-04 12:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Grant Likely <grant.likely@linaro.org>

Reserved memory nodes allow for the reservation of static (fixed
address) regions, or dynamically allocated regions for a specific
purpose.

[joshc: Based on binding document proposed (in non-patch form) here:
 http://lkml.kernel.org/g/20131030134702.19B57C402A0 at trevor.secretlab.ca
 adapted to support #memory-region-cells]

Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Laura Abbott <lauraa@codeaurora.org>
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 .../bindings/reserved-memory/reserved-memory.txt   |  138 ++++++++++++++++++++
 1 file changed, 138 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt

diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
new file mode 100644
index 000000000000..a606ce90c9c4
--- /dev/null
+++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
@@ -0,0 +1,138 @@
+*** Reserved memory regions ***
+
+Reserved memory is specified as a node under the /reserved-memory node.
+The operating system shall exclude reserved memory from normal usage
+one can create child nodes describing particular reserved (excluded from
+normal use) memory regions. Such memory regions are usually designed for
+the special usage by various device drivers.
+
+Parameters for each memory region can be encoded into the device tree
+with the following nodes:
+
+/reserved-memory node
+---------------------
+#address-cells, #size-cells (required) - standard definition
+    - Should use the same values as the root node
+#memory-region-cells (required) - dictates number of cells used in the child
+                                  nodes memory-region specifier
+ranges (required) - standard definition
+    - Should be empty
+
+/reserved-memory/ child nodes
+-----------------------------
+Each child of the reserved-memory node specifies one or more regions of
+reserved memory. Each child node may either use a 'reg' property to
+specify a specific range of reserved memory, or a 'size' property with
+optional constraints to request a dynamically allocated block of memory.
+
+Following the generic-names recommended practice, node names should
+reflect the purpose of the node (ie. "framebuffer" or "dma-pool"). Unit
+address (@<address>) should be appended to the name if the node is a
+static allocation.
+
+Properties:
+Requires either a) or b) below.
+a) static allocation
+   reg (required) - standard definition
+b) dynamic allocation
+   size (required) - length based on parent's #size-cells
+                   - Size in bytes of memory to reserve.
+   alignment (optional) - length based on parent's #size-cells
+                        - Address boundary for alignment of allocation.
+   alloc-ranges (optional) - prop-encoded-array (address, length pairs).
+                           - Specifies regions of memory that are
+                             acceptable to allocate from.
+
+If both reg and size are present, then the reg property takes precedence
+and size is ignored.
+
+Additional properties:
+compatible (optional) - standard definition
+    - may contain the following strings:
+        - shared-dma-pool: This indicates a region of memory meant to be
+          used as a shared pool of DMA buffers for a set of devices. It can
+          be used by an operating system to instanciate the necessary pool
+          management subsystem if necessary.
+        - vendor specific string in the form <vendor>,[<device>-]<usage>
+no-map (optional) - empty property
+    - Indicates the operating system must not create a virtual mapping
+      of the region as part of its standard mapping of system memory,
+      nor permit speculative access to it under any circumstances other
+      than under the control of the device driver using the region.
+reusable (optional) - empty property
+    - The operating system can use the memory in this region with the
+      limitation that the device driver(s) owning the region need to be
+      able to reclaim it back. Typically that means that the operating
+      system can use that region to store volatile or cached data that
+      can be otherwise regenerated or migrated elsewhere.
+
+Linux implementation note:
+- If a "linux,cma-default" property is present, then Linux will use the
+  region for the default pool of the contiguous memory allocator.
+
+Device node references to reserved memory
+-----------------------------------------
+Regions in the /reserved-memory node may be referenced by other device
+nodes by adding a memory-region property to the device node.
+
+memory-region (optional) - phandle, specifier pairs to children of /reserved-memory
+
+Example
+-------
+This example defines 3 contiguous regions are defined for Linux kernel:
+one default of all device drivers (named linux,cma at 72000000 and 64MiB in size),
+one dedicated to the framebuffer device (named framebuffer at 78000000, 8MiB), and
+one for multimedia processing (named multimedia-memory at 77000000, 64MiB).
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	memory {
+		reg = <0x40000000 0x40000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		/* global autoconfigured region for contiguous allocations */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			#memory-region-cells = <0>;
+			size = <0x4000000>;
+			alignment = <0x2000>;
+			linux,cma-default;
+		};
+
+		display_reserved: framebuffer at 78000000 {
+			#memory-region-cells = <0>;
+			reg = <0x78000000 0x800000>;
+		};
+
+		multimedia_reserved: multimedia at 77000000 {
+			compatible = "acme,multimedia-memory";
+			#memory-region-cells = <1>;
+			reg = <0x77000000 0x4000000>;
+		};
+	};
+
+	/* ... */
+
+	fb0: video at 12300000 {
+		memory-region = <&display_reserved>;
+		/* ... */
+	};
+
+	scaler: scaler at 12500000 {
+		memory-region = <&multimedia_reserved 0xdeadbeef>;
+		/* ... */
+	};
+
+	codec: codec at 12600000 {
+		memory-region = <&multimedia_reserved 0xfeebdaed>;
+		/* ... */
+	};
+};
-- 
1.7.9.5

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

* Re: [PATCH v2 5/5] of: document bindings for reserved-memory nodes
  2014-02-04 12:09   ` Marek Szyprowski
  (?)
@ 2014-02-05 10:07     ` Grant Likely
  -1 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-05 10:07 UTC (permalink / raw)
  To: Marek Szyprowski, linux-kernel, linux-arm-kernel, linaro-mm-sig,
	devicetree, linux-doc
  Cc: Marek Szyprowski, Kyungmin Park, Benjamin Herrenschmidt,
	Arnd Bergmann, Michal Nazarewicz, Tomasz Figa, Sascha Hauer,
	Laura Abbott, Rob Herring, Olof Johansson, Pawel Moll,
	Mark Rutland, Stephen Warren, Ian Campbell, Tomasz Figa,
	Kumar Gala, Nishanth Peethambaran, Marc, Josh Cartwright

On Tue, 04 Feb 2014 13:09:33 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> From: Grant Likely <grant.likely@linaro.org>
> 
> Reserved memory nodes allow for the reservation of static (fixed
> address) regions, or dynamically allocated regions for a specific
> purpose.
> 
> [joshc: Based on binding document proposed (in non-patch form) here:
>  http://lkml.kernel.org/g/20131030134702.19B57C402A0@trevor.secretlab.ca
>  adapted to support #memory-region-cells]
> 
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Laura Abbott <lauraa@codeaurora.org>
> Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  .../bindings/reserved-memory/reserved-memory.txt   |  138 ++++++++++++++++++++
>  1 file changed, 138 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
> 
> diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
> new file mode 100644
> index 000000000000..a606ce90c9c4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
> @@ -0,0 +1,138 @@
> +*** Reserved memory regions ***
> +
> +Reserved memory is specified as a node under the /reserved-memory node.
> +The operating system shall exclude reserved memory from normal usage
> +one can create child nodes describing particular reserved (excluded from
> +normal use) memory regions. Such memory regions are usually designed for
> +the special usage by various device drivers.
> +
> +Parameters for each memory region can be encoded into the device tree
> +with the following nodes:
> +
> +/reserved-memory node
> +---------------------
> +#address-cells, #size-cells (required) - standard definition
> +    - Should use the same values as the root node
> +#memory-region-cells (required) - dictates number of cells used in the child
> +                                  nodes memory-region specifier

I don't think this isn't defined well enough. These reserved regions may
not have a driver attached to them, so there is no central agent to
decide what the specifier means. That leaves the interpretation of
the memory region in the hands of the client drivers. How do you see the
specifier getting parsed and used?

Otherwise the binding looks good to me. Also, please add my s-o-b line
to the patch (instead of a-b because I authored part of the text)

Signed-off-by: Grant Likely <grant.likely@linaro.org>

g.

> +ranges (required) - standard definition
> +    - Should be empty
> +
> +/reserved-memory/ child nodes
> +-----------------------------
> +Each child of the reserved-memory node specifies one or more regions of
> +reserved memory. Each child node may either use a 'reg' property to
> +specify a specific range of reserved memory, or a 'size' property with
> +optional constraints to request a dynamically allocated block of memory.
> +
> +Following the generic-names recommended practice, node names should
> +reflect the purpose of the node (ie. "framebuffer" or "dma-pool"). Unit
> +address (@<address>) should be appended to the name if the node is a
> +static allocation.
> +
> +Properties:
> +Requires either a) or b) below.
> +a) static allocation
> +   reg (required) - standard definition
> +b) dynamic allocation
> +   size (required) - length based on parent's #size-cells
> +                   - Size in bytes of memory to reserve.
> +   alignment (optional) - length based on parent's #size-cells
> +                        - Address boundary for alignment of allocation.
> +   alloc-ranges (optional) - prop-encoded-array (address, length pairs).
> +                           - Specifies regions of memory that are
> +                             acceptable to allocate from.
> +
> +If both reg and size are present, then the reg property takes precedence
> +and size is ignored.
> +
> +Additional properties:
> +compatible (optional) - standard definition
> +    - may contain the following strings:
> +        - shared-dma-pool: This indicates a region of memory meant to be
> +          used as a shared pool of DMA buffers for a set of devices. It can
> +          be used by an operating system to instanciate the necessary pool
> +          management subsystem if necessary.
> +        - vendor specific string in the form <vendor>,[<device>-]<usage>
> +no-map (optional) - empty property
> +    - Indicates the operating system must not create a virtual mapping
> +      of the region as part of its standard mapping of system memory,
> +      nor permit speculative access to it under any circumstances other
> +      than under the control of the device driver using the region.
> +reusable (optional) - empty property
> +    - The operating system can use the memory in this region with the
> +      limitation that the device driver(s) owning the region need to be
> +      able to reclaim it back. Typically that means that the operating
> +      system can use that region to store volatile or cached data that
> +      can be otherwise regenerated or migrated elsewhere.
> +
> +Linux implementation note:
> +- If a "linux,cma-default" property is present, then Linux will use the
> +  region for the default pool of the contiguous memory allocator.
> +
> +Device node references to reserved memory
> +-----------------------------------------
> +Regions in the /reserved-memory node may be referenced by other device
> +nodes by adding a memory-region property to the device node.
> +
> +memory-region (optional) - phandle, specifier pairs to children of /reserved-memory
> +
> +Example
> +-------
> +This example defines 3 contiguous regions are defined for Linux kernel:
> +one default of all device drivers (named linux,cma@72000000 and 64MiB in size),
> +one dedicated to the framebuffer device (named framebuffer@78000000, 8MiB), and
> +one for multimedia processing (named multimedia-memory@77000000, 64MiB).
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	memory {
> +		reg = <0x40000000 0x40000000>;
> +	};
> +
> +	reserved-memory {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		/* global autoconfigured region for contiguous allocations */
> +		linux,cma {
> +			compatible = "shared-dma-pool";
> +			reusable;
> +			#memory-region-cells = <0>;
> +			size = <0x4000000>;
> +			alignment = <0x2000>;
> +			linux,cma-default;
> +		};
> +
> +		display_reserved: framebuffer@78000000 {
> +			#memory-region-cells = <0>;
> +			reg = <0x78000000 0x800000>;
> +		};
> +
> +		multimedia_reserved: multimedia@77000000 {
> +			compatible = "acme,multimedia-memory";
> +			#memory-region-cells = <1>;
> +			reg = <0x77000000 0x4000000>;
> +		};
> +	};
> +
> +	/* ... */
> +
> +	fb0: video@12300000 {
> +		memory-region = <&display_reserved>;
> +		/* ... */
> +	};
> +
> +	scaler: scaler@12500000 {
> +		memory-region = <&multimedia_reserved 0xdeadbeef>;
> +		/* ... */
> +	};
> +
> +	codec: codec@12600000 {
> +		memory-region = <&multimedia_reserved 0xfeebdaed>;
> +		/* ... */
> +	};
> +};
> -- 
> 1.7.9.5
> 


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

* Re: [PATCH v2 5/5] of: document bindings for reserved-memory nodes
@ 2014-02-05 10:07     ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-05 10:07 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linaro-mm-sig, devicetree, linux-doc
  Cc: Marek Szyprowski, Kyungmin Park, Benjamin Herrenschmidt,
	Arnd Bergmann, Michal Nazarewicz, Tomasz Figa, Sascha Hauer,
	Laura Abbott, Rob Herring, Olof Johansson, Pawel Moll,
	Mark Rutland, Stephen Warren, Ian Campbell, Tomasz Figa,
	Kumar Gala, Nishanth Peethambaran, Marc, Josh Cartwright

On Tue, 04 Feb 2014 13:09:33 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> From: Grant Likely <grant.likely@linaro.org>
> 
> Reserved memory nodes allow for the reservation of static (fixed
> address) regions, or dynamically allocated regions for a specific
> purpose.
> 
> [joshc: Based on binding document proposed (in non-patch form) here:
>  http://lkml.kernel.org/g/20131030134702.19B57C402A0@trevor.secretlab.ca
>  adapted to support #memory-region-cells]
> 
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Laura Abbott <lauraa@codeaurora.org>
> Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  .../bindings/reserved-memory/reserved-memory.txt   |  138 ++++++++++++++++++++
>  1 file changed, 138 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
> 
> diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
> new file mode 100644
> index 000000000000..a606ce90c9c4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
> @@ -0,0 +1,138 @@
> +*** Reserved memory regions ***
> +
> +Reserved memory is specified as a node under the /reserved-memory node.
> +The operating system shall exclude reserved memory from normal usage
> +one can create child nodes describing particular reserved (excluded from
> +normal use) memory regions. Such memory regions are usually designed for
> +the special usage by various device drivers.
> +
> +Parameters for each memory region can be encoded into the device tree
> +with the following nodes:
> +
> +/reserved-memory node
> +---------------------
> +#address-cells, #size-cells (required) - standard definition
> +    - Should use the same values as the root node
> +#memory-region-cells (required) - dictates number of cells used in the child
> +                                  nodes memory-region specifier

I don't think this isn't defined well enough. These reserved regions may
not have a driver attached to them, so there is no central agent to
decide what the specifier means. That leaves the interpretation of
the memory region in the hands of the client drivers. How do you see the
specifier getting parsed and used?

Otherwise the binding looks good to me. Also, please add my s-o-b line
to the patch (instead of a-b because I authored part of the text)

Signed-off-by: Grant Likely <grant.likely@linaro.org>

g.

> +ranges (required) - standard definition
> +    - Should be empty
> +
> +/reserved-memory/ child nodes
> +-----------------------------
> +Each child of the reserved-memory node specifies one or more regions of
> +reserved memory. Each child node may either use a 'reg' property to
> +specify a specific range of reserved memory, or a 'size' property with
> +optional constraints to request a dynamically allocated block of memory.
> +
> +Following the generic-names recommended practice, node names should
> +reflect the purpose of the node (ie. "framebuffer" or "dma-pool"). Unit
> +address (@<address>) should be appended to the name if the node is a
> +static allocation.
> +
> +Properties:
> +Requires either a) or b) below.
> +a) static allocation
> +   reg (required) - standard definition
> +b) dynamic allocation
> +   size (required) - length based on parent's #size-cells
> +                   - Size in bytes of memory to reserve.
> +   alignment (optional) - length based on parent's #size-cells
> +                        - Address boundary for alignment of allocation.
> +   alloc-ranges (optional) - prop-encoded-array (address, length pairs).
> +                           - Specifies regions of memory that are
> +                             acceptable to allocate from.
> +
> +If both reg and size are present, then the reg property takes precedence
> +and size is ignored.
> +
> +Additional properties:
> +compatible (optional) - standard definition
> +    - may contain the following strings:
> +        - shared-dma-pool: This indicates a region of memory meant to be
> +          used as a shared pool of DMA buffers for a set of devices. It can
> +          be used by an operating system to instanciate the necessary pool
> +          management subsystem if necessary.
> +        - vendor specific string in the form <vendor>,[<device>-]<usage>
> +no-map (optional) - empty property
> +    - Indicates the operating system must not create a virtual mapping
> +      of the region as part of its standard mapping of system memory,
> +      nor permit speculative access to it under any circumstances other
> +      than under the control of the device driver using the region.
> +reusable (optional) - empty property
> +    - The operating system can use the memory in this region with the
> +      limitation that the device driver(s) owning the region need to be
> +      able to reclaim it back. Typically that means that the operating
> +      system can use that region to store volatile or cached data that
> +      can be otherwise regenerated or migrated elsewhere.
> +
> +Linux implementation note:
> +- If a "linux,cma-default" property is present, then Linux will use the
> +  region for the default pool of the contiguous memory allocator.
> +
> +Device node references to reserved memory
> +-----------------------------------------
> +Regions in the /reserved-memory node may be referenced by other device
> +nodes by adding a memory-region property to the device node.
> +
> +memory-region (optional) - phandle, specifier pairs to children of /reserved-memory
> +
> +Example
> +-------
> +This example defines 3 contiguous regions are defined for Linux kernel:
> +one default of all device drivers (named linux,cma@72000000 and 64MiB in size),
> +one dedicated to the framebuffer device (named framebuffer@78000000, 8MiB), and
> +one for multimedia processing (named multimedia-memory@77000000, 64MiB).
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	memory {
> +		reg = <0x40000000 0x40000000>;
> +	};
> +
> +	reserved-memory {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		/* global autoconfigured region for contiguous allocations */
> +		linux,cma {
> +			compatible = "shared-dma-pool";
> +			reusable;
> +			#memory-region-cells = <0>;
> +			size = <0x4000000>;
> +			alignment = <0x2000>;
> +			linux,cma-default;
> +		};
> +
> +		display_reserved: framebuffer@78000000 {
> +			#memory-region-cells = <0>;
> +			reg = <0x78000000 0x800000>;
> +		};
> +
> +		multimedia_reserved: multimedia@77000000 {
> +			compatible = "acme,multimedia-memory";
> +			#memory-region-cells = <1>;
> +			reg = <0x77000000 0x4000000>;
> +		};
> +	};
> +
> +	/* ... */
> +
> +	fb0: video@12300000 {
> +		memory-region = <&display_reserved>;
> +		/* ... */
> +	};
> +
> +	scaler: scaler@12500000 {
> +		memory-region = <&multimedia_reserved 0xdeadbeef>;
> +		/* ... */
> +	};
> +
> +	codec: codec@12600000 {
> +		memory-region = <&multimedia_reserved 0xfeebdaed>;
> +		/* ... */
> +	};
> +};
> -- 
> 1.7.9.5
> 


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

* [PATCH v2 5/5] of: document bindings for reserved-memory nodes
@ 2014-02-05 10:07     ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-05 10:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 04 Feb 2014 13:09:33 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> From: Grant Likely <grant.likely@linaro.org>
> 
> Reserved memory nodes allow for the reservation of static (fixed
> address) regions, or dynamically allocated regions for a specific
> purpose.
> 
> [joshc: Based on binding document proposed (in non-patch form) here:
>  http://lkml.kernel.org/g/20131030134702.19B57C402A0 at trevor.secretlab.ca
>  adapted to support #memory-region-cells]
> 
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Laura Abbott <lauraa@codeaurora.org>
> Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  .../bindings/reserved-memory/reserved-memory.txt   |  138 ++++++++++++++++++++
>  1 file changed, 138 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
> 
> diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
> new file mode 100644
> index 000000000000..a606ce90c9c4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
> @@ -0,0 +1,138 @@
> +*** Reserved memory regions ***
> +
> +Reserved memory is specified as a node under the /reserved-memory node.
> +The operating system shall exclude reserved memory from normal usage
> +one can create child nodes describing particular reserved (excluded from
> +normal use) memory regions. Such memory regions are usually designed for
> +the special usage by various device drivers.
> +
> +Parameters for each memory region can be encoded into the device tree
> +with the following nodes:
> +
> +/reserved-memory node
> +---------------------
> +#address-cells, #size-cells (required) - standard definition
> +    - Should use the same values as the root node
> +#memory-region-cells (required) - dictates number of cells used in the child
> +                                  nodes memory-region specifier

I don't think this isn't defined well enough. These reserved regions may
not have a driver attached to them, so there is no central agent to
decide what the specifier means. That leaves the interpretation of
the memory region in the hands of the client drivers. How do you see the
specifier getting parsed and used?

Otherwise the binding looks good to me. Also, please add my s-o-b line
to the patch (instead of a-b because I authored part of the text)

Signed-off-by: Grant Likely <grant.likely@linaro.org>

g.

> +ranges (required) - standard definition
> +    - Should be empty
> +
> +/reserved-memory/ child nodes
> +-----------------------------
> +Each child of the reserved-memory node specifies one or more regions of
> +reserved memory. Each child node may either use a 'reg' property to
> +specify a specific range of reserved memory, or a 'size' property with
> +optional constraints to request a dynamically allocated block of memory.
> +
> +Following the generic-names recommended practice, node names should
> +reflect the purpose of the node (ie. "framebuffer" or "dma-pool"). Unit
> +address (@<address>) should be appended to the name if the node is a
> +static allocation.
> +
> +Properties:
> +Requires either a) or b) below.
> +a) static allocation
> +   reg (required) - standard definition
> +b) dynamic allocation
> +   size (required) - length based on parent's #size-cells
> +                   - Size in bytes of memory to reserve.
> +   alignment (optional) - length based on parent's #size-cells
> +                        - Address boundary for alignment of allocation.
> +   alloc-ranges (optional) - prop-encoded-array (address, length pairs).
> +                           - Specifies regions of memory that are
> +                             acceptable to allocate from.
> +
> +If both reg and size are present, then the reg property takes precedence
> +and size is ignored.
> +
> +Additional properties:
> +compatible (optional) - standard definition
> +    - may contain the following strings:
> +        - shared-dma-pool: This indicates a region of memory meant to be
> +          used as a shared pool of DMA buffers for a set of devices. It can
> +          be used by an operating system to instanciate the necessary pool
> +          management subsystem if necessary.
> +        - vendor specific string in the form <vendor>,[<device>-]<usage>
> +no-map (optional) - empty property
> +    - Indicates the operating system must not create a virtual mapping
> +      of the region as part of its standard mapping of system memory,
> +      nor permit speculative access to it under any circumstances other
> +      than under the control of the device driver using the region.
> +reusable (optional) - empty property
> +    - The operating system can use the memory in this region with the
> +      limitation that the device driver(s) owning the region need to be
> +      able to reclaim it back. Typically that means that the operating
> +      system can use that region to store volatile or cached data that
> +      can be otherwise regenerated or migrated elsewhere.
> +
> +Linux implementation note:
> +- If a "linux,cma-default" property is present, then Linux will use the
> +  region for the default pool of the contiguous memory allocator.
> +
> +Device node references to reserved memory
> +-----------------------------------------
> +Regions in the /reserved-memory node may be referenced by other device
> +nodes by adding a memory-region property to the device node.
> +
> +memory-region (optional) - phandle, specifier pairs to children of /reserved-memory
> +
> +Example
> +-------
> +This example defines 3 contiguous regions are defined for Linux kernel:
> +one default of all device drivers (named linux,cma at 72000000 and 64MiB in size),
> +one dedicated to the framebuffer device (named framebuffer at 78000000, 8MiB), and
> +one for multimedia processing (named multimedia-memory at 77000000, 64MiB).
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	memory {
> +		reg = <0x40000000 0x40000000>;
> +	};
> +
> +	reserved-memory {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		/* global autoconfigured region for contiguous allocations */
> +		linux,cma {
> +			compatible = "shared-dma-pool";
> +			reusable;
> +			#memory-region-cells = <0>;
> +			size = <0x4000000>;
> +			alignment = <0x2000>;
> +			linux,cma-default;
> +		};
> +
> +		display_reserved: framebuffer at 78000000 {
> +			#memory-region-cells = <0>;
> +			reg = <0x78000000 0x800000>;
> +		};
> +
> +		multimedia_reserved: multimedia at 77000000 {
> +			compatible = "acme,multimedia-memory";
> +			#memory-region-cells = <1>;
> +			reg = <0x77000000 0x4000000>;
> +		};
> +	};
> +
> +	/* ... */
> +
> +	fb0: video at 12300000 {
> +		memory-region = <&display_reserved>;
> +		/* ... */
> +	};
> +
> +	scaler: scaler at 12500000 {
> +		memory-region = <&multimedia_reserved 0xdeadbeef>;
> +		/* ... */
> +	};
> +
> +	codec: codec at 12600000 {
> +		memory-region = <&multimedia_reserved 0xfeebdaed>;
> +		/* ... */
> +	};
> +};
> -- 
> 1.7.9.5
> 

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

* Re: [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
  2014-02-04 12:09   ` Marek Szyprowski
  (?)
@ 2014-02-05 10:15     ` Grant Likely
  -1 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-05 10:15 UTC (permalink / raw)
  To: Marek Szyprowski, linux-kernel, linux-arm-kernel, linaro-mm-sig,
	devicetree, linux-doc
  Cc: Marek Szyprowski, Kyungmin Park, Benjamin Herrenschmidt,
	Arnd Bergmann, Michal Nazarewicz, Tomasz Figa, Sascha Hauer,
	Laura Abbott, Rob Herring, Olof Johansson, Pawel Moll,
	Mark Rutland, Stephen Warren, Ian Campbell, Tomasz Figa,
	Kumar Gala, Nishanth Peethambaran, Marc, Josh Cartwright

On Tue, 04 Feb 2014 13:09:32 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> Enable reserved memory initialization from device tree.
> 
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Laura Abbott <lauraa@codeaurora.org>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  arch/arm/mm/init.c |    3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> index 804d61566a53..ebafdb479410 100644
> --- a/arch/arm/mm/init.c
> +++ b/arch/arm/mm/init.c
> @@ -17,6 +17,7 @@
>  #include <linux/nodemask.h>
>  #include <linux/initrd.h>
>  #include <linux/of_fdt.h>
> +#include <linux/of_reserved_mem.h>
>  #include <linux/highmem.h>
>  #include <linux/gfp.h>
>  #include <linux/memblock.h>
> @@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
>  	if (mdesc->reserve)
>  		mdesc->reserve();
>  
> +	early_init_dt_scan_reserved_mem();
> +

The new binding is being made fundamental. If the reserved-memory node
is present, then it needs to be honored, even if the kernel doesn't know
how to use the regions. Therefore, This needs to be unconditional for
all architectures. The hook should be called in early_init_dt_scan()
(drivers/of/fdt.c) immediately after the early_init_dt_scan_memory()
hook.

>  	/*
>  	 * reserve memory for DMA contigouos allocations,
>  	 * must come from DMA area inside low memory
> -- 
> 1.7.9.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


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

* Re: [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
@ 2014-02-05 10:15     ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-05 10:15 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linaro-mm-sig, devicetree, linux-doc
  Cc: Marek Szyprowski, Kyungmin Park, Benjamin Herrenschmidt,
	Arnd Bergmann, Michal Nazarewicz, Tomasz Figa, Sascha Hauer,
	Laura Abbott, Rob Herring, Olof Johansson, Pawel Moll,
	Mark Rutland, Stephen Warren, Ian Campbell, Tomasz Figa,
	Kumar Gala, Nishanth Peethambaran, Marc, Josh Cartwright

On Tue, 04 Feb 2014 13:09:32 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> Enable reserved memory initialization from device tree.
> 
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Laura Abbott <lauraa@codeaurora.org>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  arch/arm/mm/init.c |    3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> index 804d61566a53..ebafdb479410 100644
> --- a/arch/arm/mm/init.c
> +++ b/arch/arm/mm/init.c
> @@ -17,6 +17,7 @@
>  #include <linux/nodemask.h>
>  #include <linux/initrd.h>
>  #include <linux/of_fdt.h>
> +#include <linux/of_reserved_mem.h>
>  #include <linux/highmem.h>
>  #include <linux/gfp.h>
>  #include <linux/memblock.h>
> @@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
>  	if (mdesc->reserve)
>  		mdesc->reserve();
>  
> +	early_init_dt_scan_reserved_mem();
> +

The new binding is being made fundamental. If the reserved-memory node
is present, then it needs to be honored, even if the kernel doesn't know
how to use the regions. Therefore, This needs to be unconditional for
all architectures. The hook should be called in early_init_dt_scan()
(drivers/of/fdt.c) immediately after the early_init_dt_scan_memory()
hook.

>  	/*
>  	 * reserve memory for DMA contigouos allocations,
>  	 * must come from DMA area inside low memory
> -- 
> 1.7.9.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


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

* [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
@ 2014-02-05 10:15     ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-05 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 04 Feb 2014 13:09:32 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> Enable reserved memory initialization from device tree.
> 
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Laura Abbott <lauraa@codeaurora.org>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  arch/arm/mm/init.c |    3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> index 804d61566a53..ebafdb479410 100644
> --- a/arch/arm/mm/init.c
> +++ b/arch/arm/mm/init.c
> @@ -17,6 +17,7 @@
>  #include <linux/nodemask.h>
>  #include <linux/initrd.h>
>  #include <linux/of_fdt.h>
> +#include <linux/of_reserved_mem.h>
>  #include <linux/highmem.h>
>  #include <linux/gfp.h>
>  #include <linux/memblock.h>
> @@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
>  	if (mdesc->reserve)
>  		mdesc->reserve();
>  
> +	early_init_dt_scan_reserved_mem();
> +

The new binding is being made fundamental. If the reserved-memory node
is present, then it needs to be honored, even if the kernel doesn't know
how to use the regions. Therefore, This needs to be unconditional for
all architectures. The hook should be called in early_init_dt_scan()
(drivers/of/fdt.c) immediately after the early_init_dt_scan_memory()
hook.

>  	/*
>  	 * reserve memory for DMA contigouos allocations,
>  	 * must come from DMA area inside low memory
> -- 
> 1.7.9.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

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

* Re: [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
  2014-02-04 12:09   ` Marek Szyprowski
  (?)
@ 2014-02-05 11:05     ` Grant Likely
  -1 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-05 11:05 UTC (permalink / raw)
  To: Marek Szyprowski, linux-kernel, linux-arm-kernel, linaro-mm-sig,
	devicetree, linux-doc
  Cc: Marek Szyprowski, Kyungmin Park, Benjamin Herrenschmidt,
	Arnd Bergmann, Michal Nazarewicz, Tomasz Figa, Sascha Hauer,
	Laura Abbott, Rob Herring, Olof Johansson, Pawel Moll,
	Mark Rutland, Stephen Warren, Ian Campbell, Tomasz Figa,
	Kumar Gala, Nishanth Peethambaran, Marc, Josh Cartwright

On Tue, 04 Feb 2014 13:09:29 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> This patch adds device tree support for contiguous and reserved memory
> regions defined in device tree.
> 
> Large memory blocks can be reliably reserved only during early boot.
> This must happen before the whole memory management subsystem is
> initialized, because we need to ensure that the given contiguous blocks
> are not yet allocated by kernel. Also it must happen before kernel
> mappings for the whole low memory are created, to ensure that there will
> be no mappings (for reserved blocks) or mapping with special properties
> can be created (for CMA blocks). This all happens before device tree
> structures are unflattened, so we need to get reserved memory layout
> directly from fdt.
> 
> Later, those reserved memory regions are assigned to devices on each
> device structure initialization.
> 
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Laura Abbott <lauraa@codeaurora.org>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> [joshc: rework to implement new DT binding, provide mechanism for
>  plugging in new reserved-memory node handlers via
>  RESERVEDMEM_OF_DECLARE]
> Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
> [mszyprow: little code cleanup]
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/of/Kconfig                |    6 +
>  drivers/of/Makefile               |    1 +
>  drivers/of/of_reserved_mem.c      |  219 +++++++++++++++++++++++++++++++++++++
>  drivers/of/platform.c             |    7 ++
>  include/asm-generic/vmlinux.lds.h |   11 ++
>  include/linux/of_reserved_mem.h   |   62 +++++++++++
>  6 files changed, 306 insertions(+)
>  create mode 100644 drivers/of/of_reserved_mem.c
>  create mode 100644 include/linux/of_reserved_mem.h
> 
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index c6973f101a3e..aba13df56f3a 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -75,4 +75,10 @@ config OF_MTD
>  	depends on MTD
>  	def_bool y
>  
> +config OF_RESERVED_MEM
> +	depends on HAVE_MEMBLOCK
> +	def_bool y
> +	help
> +	  Helpers to allow for reservation of memory regions
> +
>  endmenu # OF
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index efd05102c405..ed9660adad77 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
>  obj-$(CONFIG_OF_PCI)	+= of_pci.o
>  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
>  obj-$(CONFIG_OF_MTD)	+= of_mtd.o
> +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> new file mode 100644
> index 000000000000..f17cd56e68d9
> --- /dev/null
> +++ b/drivers/of/of_reserved_mem.c
> @@ -0,0 +1,219 @@
> +/*
> + * Device tree based initialization code for reserved memory.
> + *
> + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com
> + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
> + * Author: Josh Cartwright <joshc@codeaurora.org>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of the
> + * License or (at your optional) any later version of the license.
> + */
> +#include <linux/memblock.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/of_fdt.h>
> +#include <linux/of_platform.h>
> +#include <linux/mm.h>
> +#include <linux/sizes.h>
> +#include <linux/of_reserved_mem.h>
> +
> +#define MAX_RESERVED_REGIONS	16
> +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
> +static int reserved_mem_count;
> +
> +int __init of_parse_flat_dt_reg(unsigned long node, const char *uname,
> +				   phys_addr_t *base, phys_addr_t *size)

Useful utility function; move to drivers/of/fdt.c

> +{
> +	unsigned long len;
> +	__be32 *prop;
> +
> +	prop = of_get_flat_dt_prop(node, "reg", &len);
> +	if (!prop)
> +		return -EINVAL;
> +
> +	if (len < (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) {
> +		pr_err("Reserved memory: invalid reg property in '%s' node.\n",
> +				uname);
> +		return -EINVAL;
> +	}

This is /okay/ for an initial implementation, but it is naive. While I
suggested making #address-cells and #size-cells equal the root node
values for the purpose of simplicity, it should still be perfectly valid
to have different values if the ranges property is correctly formed.

> +
> +	*base = dt_mem_next_cell(dt_root_addr_cells, &prop);
> +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);

Future enhancement; allow for parsing more than just the first reg
tuple.

> +	return 0;
> +}

> +
> +int __init of_parse_flat_dt_size(unsigned long node, const char *uname,
> +				    phys_addr_t *size)
> +{
> +	unsigned long len;
> +	__be32 *prop;
> +
> +	prop = of_get_flat_dt_prop(node, "size", &len);
> +	if (!prop)
> +		return -EINVAL;
> +
> +	if (len < dt_root_size_cells * sizeof(__be32)) {
> +		pr_err("Reserved memory: invalid size property in '%s' node.\n",
> +				uname);
> +		return -EINVAL;
> +	}

More than that, the size should be dead on. '==' would be the correct
test I think.

> +
> +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
> +	return 0;
> +}
> +
> +static int __init rmem_default_early_setup(struct reserved_mem *rmem,
> +					   unsigned long node,
> +					   const char *uname)
> +{
> +	int err;
> +
> +	if (of_get_flat_dt_prop(node, "compatible", NULL))
> +		return -EINVAL;
> +
> +	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
> +	if (err)
> +		return err;
> +
> +	if (of_get_flat_dt_prop(node, "no-map", NULL))
> +		err = memblock_remove(rmem->base, rmem->size);
> +	else
> +		err = memblock_reserve(rmem->base, rmem->size);

This is the only dependency on memblock. Make it an arch hook, and
create a default __weak implementation:

#if defined(CONFIG_HAVE_MEMBLOCK)
int __init __weak early_init_dt_reserve_memory_arch(u64 base, u64 size, bool nomap)
{
	if (nomap)
		return memblock_remove(base, size);
	return memblock_reserve(base, size);
}
#else
int __init __weak early_init_dt_reserve_memory_arch(u64 base, u64 size, bool nomap)
{
	pr_error("Reserved memory not supported, ignoring range 0x%llx - 0x%llx%s\n",
		base, size, nomap ? " (nomap)" : "");
}
#endif

> +
> +	if (err == 0)
> +		pr_info("Reserved memory: found '%s', memory base %pa, size %ld MiB\n",
> +			uname, &rmem->base, (unsigned long)rmem->size / SZ_1M);

pr_info will be too chatty I think. pr_debug please.

> +
> +	return err;
> +}
> +
> +static const struct of_device_id rmem_default_id
> +	__used __section(__reservedmem_of_table_end) = {
> +	.data		= rmem_default_early_setup,
> +};

I was going to say this isn't very type safe and that the only reason to
use of_device_id is when using of_match_node() which will iterate a
table for you. But reading further I see you're handling type checking
in the macro so this is okay.

> +
> +static int __init fdt_scan_reserved_mem(unsigned long node, const char *uname,
> +					int depth, void *data)

Move this function to fdt.c. It should be treated as a fundamental part
of memory node parsing. It should also always be enabled, regardless of
the CONFIG_OF_RESERVED_MEMORY state because the region should always be
set aside even when the kernel doesn't know how to use it.

> +{
> +	struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
> +	extern const struct of_device_id __reservedmem_of_table[];
> +	const struct of_device_id *id;
> +	const char *status;
> +
> +	if (reserved_mem_count == ARRAY_SIZE(reserved_mem)) {
> +		pr_err("Reserved memory: not enough space all defined regions.\n");
> +		return -ENOSPC;
> +	}

It is not okay to bail here. If a region is reserved, then the kernel
*MUST* honor it, even if drivers cannot make use of it. As a bare
minimum it should be removed from the memblock pool.

> +
> +	status = of_get_flat_dt_prop(node, "status", NULL);
> +	if (status && strcmp(status, "okay") != 0)
> +		return 0;
> +
> +	/*
> +	 * The default handler above ensures this section is terminated with a
> +	 * id whose compatible string is empty
> +	 */
> +	for (id = __reservedmem_of_table; id <= &rmem_default_id; id++) {
> +		reservedmem_of_init_fn initfn = id->data;
> +		const char *compat = id->compatible;
> +
> +		if (compat[0] && !of_flat_dt_is_compatible(node, compat))
> +			continue;
> +
> +		if (initfn(rmem, node, uname) == 0) {
> +			pr_info("Reserved memory: created %s node, compatible id %s\n",
> +				uname, compat);
> +			rmem->name = uname;
> +			reserved_mem_count++;
> +			break;
> +		}
> +	}

What would be the condition that a special setup hook is called, but the
memory is not removed from the memblock pool? I seems wrong to me that
memory blocks wouldn't always get removed from main memory; even if
special setup code is executed on them.

By calling out to extra setup functions it means that each one of them
needs to implement its own memory removal code and get it correct. There
is a strong possibility for bugs there.

> +
> +	return 0;
> +}
> +
> +static struct reserved_mem *find_rmem(struct device_node *np)
> +{
> +	const char *name;
> +	unsigned int i;
> +
> +	name = kbasename(np->full_name);
> +
> +	for (i = 0; i < reserved_mem_count; i++)
> +		if (strcmp(name, reserved_mem[i].name) == 0)
> +			return &reserved_mem[i];

This looks fragile. It needs to match on the full path, not just
kbasename(), but that is expensive. However, all reserved regions should
have a phandle. You can use that for matching.

> +
> +	return NULL;
> +}
> +
> +/**
> + * of_reserved_mem_device_init() - assign reserved memory region to given device
> + *
> + * This function assign memory region pointed by "memory-region" device tree
> + * property to the given device.
> + */
> +void of_reserved_mem_device_init(struct device *dev)
> +{
> +	struct device_node *np = dev->of_node;
> +	struct reserved_mem *rmem;
> +	struct of_phandle_args s;
> +	unsigned int i;
> +
> +	for (i = 0; of_parse_phandle_with_args(np, "memory-region",
> +				"#memory-region-cells", i, &s) == 0; i++) {
> +
> +		rmem = find_rmem(s.np);
> +		if (!rmem || !rmem->ops || !rmem->ops->device_init) {
> +			of_node_put(s.np);
> +			continue;
> +		}
> +
> +		rmem->ops->device_init(rmem, dev, &s);
> +		dev_info(dev, "assigned reserved memory node %s\n",
> +			 rmem->name);
> +		of_node_put(s.np);
> +		break;
> +	}
> +}
> +
> +/**
> + * of_reserved_mem_device_release() - release reserved memory device structures
> + *
> + * This function releases structures allocated for memory region handling for
> + * the given device.
> + */
> +void of_reserved_mem_device_release(struct device *dev)
> +{
> +	struct device_node *np = dev->of_node;
> +	struct reserved_mem *rmem;
> +	struct of_phandle_args s;
> +	unsigned int i;
> +
> +	for (i = 0; of_parse_phandle_with_args(np, "memory-region",
> +				"#memory-region-cells", i, &s) == 0; i++) {
> +
> +		rmem = find_rmem(s.np);
> +		if (rmem && rmem->ops && rmem->ops->device_release)
> +			rmem->ops->device_release(rmem, dev);
> +
> +		of_node_put(s.np);
> +	}
> +}
> +
> +/**
> + * early_init_dt_scan_reserved_mem() - create reserved memory regions
> + *
> + * This function grabs memory from early allocator for device exclusive use
> + * defined in device tree structures. It should be called by arch specific code
> + * once the early allocator (memblock) has been activated and all other
> + * subsystems have already allocated/reserved memory.

As commented on patch 4, this should be called by common parsing code,
not arch code.

Why do you require other subsystems to allocate/reserve memory before
the reserved regions? I would think that the reserved regions declared
in the device tree would take precedence.

> + */
> +void __init early_init_dt_scan_reserved_mem(void)
> +{
> +	of_scan_flat_dt_by_path("/reserved-memory", fdt_scan_reserved_mem,
> +				NULL);
> +}
> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> index 404d1daebefa..3df0b1826e8b 100644
> --- a/drivers/of/platform.c
> +++ b/drivers/of/platform.c
> @@ -21,6 +21,7 @@
>  #include <linux/of_device.h>
>  #include <linux/of_irq.h>
>  #include <linux/of_platform.h>
> +#include <linux/of_reserved_mem.h>
>  #include <linux/platform_device.h>
>  
>  const struct of_device_id of_default_bus_match_table[] = {
> @@ -220,6 +221,8 @@ static struct platform_device *of_platform_device_create_pdata(
>  	dev->dev.bus = &platform_bus_type;
>  	dev->dev.platform_data = platform_data;
>  
> +	of_reserved_mem_device_init(&dev->dev);
> +
>  	/* We do not fill the DMA ops for platform devices by default.
>  	 * This is currently the responsibility of the platform code
>  	 * to do such, possibly using a device notifier
> @@ -227,6 +230,7 @@ static struct platform_device *of_platform_device_create_pdata(
>  
>  	if (of_device_add(dev) != 0) {
>  		platform_device_put(dev);
> +		of_reserved_mem_device_release(&dev->dev);
>  		return NULL;
>  	}
>  
> @@ -282,6 +286,8 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
>  	else
>  		of_device_make_bus_id(&dev->dev);
>  
> +	of_reserved_mem_device_init(&dev->dev);
> +
>  	/* Allow the HW Peripheral ID to be overridden */
>  	prop = of_get_property(node, "arm,primecell-periphid", NULL);
>  	if (prop)
> @@ -308,6 +314,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
>  	return dev;
>  
>  err_free:
> +	of_reserved_mem_device_release(&dev->dev);
>  	amba_device_put(dev);
>  	return NULL;
>  }
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index bc2121fa9132..f10f64fcc815 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -167,6 +167,16 @@
>  #define CLK_OF_TABLES()
>  #endif
>  
> +#ifdef CONFIG_OF_RESERVED_MEM
> +#define RESERVEDMEM_OF_TABLES()				\
> +	. = ALIGN(8);					\
> +	VMLINUX_SYMBOL(__reservedmem_of_table) = .;	\
> +	*(__reservedmem_of_table)			\
> +	*(__reservedmem_of_table_end)
> +#else
> +#define RESERVEDMEM_OF_TABLES()
> +#endif
> +
>  #define KERNEL_DTB()							\
>  	STRUCT_ALIGN();							\
>  	VMLINUX_SYMBOL(__dtb_start) = .;				\
> @@ -490,6 +500,7 @@
>  	TRACE_SYSCALLS()						\
>  	MEM_DISCARD(init.rodata)					\
>  	CLK_OF_TABLES()							\
> +	RESERVEDMEM_OF_TABLES()						\
>  	CLKSRC_OF_TABLES()						\
>  	KERNEL_DTB()							\
>  	IRQCHIP_OF_MATCH_TABLE()
> diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
> new file mode 100644
> index 000000000000..41f43828e1db
> --- /dev/null
> +++ b/include/linux/of_reserved_mem.h
> @@ -0,0 +1,62 @@
> +#ifndef __OF_RESERVED_MEM_H
> +#define __OF_RESERVED_MEM_H
> +
> +struct cma;
> +struct platform_device;
> +struct of_phandle_args;
> +struct reserved_mem_ops;
> +
> +struct reserved_mem {
> +	const char			*name;
> +	const struct reserved_mem_ops	*ops;
> +	phys_addr_t			base;
> +	phys_addr_t			size;
> +	void				*priv;
> +};
> +
> +struct reserved_mem_ops {
> +	void	(*device_init)(struct reserved_mem *rmem,
> +			       struct device *dev,
> +			       struct of_phandle_args *args);
> +	void	(*device_release)(struct reserved_mem *rmem,
> +				  struct device *dev);
> +};
> +
> +typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem,
> +				      unsigned long node, const char *uname);
> +
> +#ifdef CONFIG_OF_RESERVED_MEM
> +void of_reserved_mem_device_init(struct device *dev);
> +void of_reserved_mem_device_release(struct device *dev);
> +void early_init_dt_scan_reserved_mem(void);
> +
> +int of_parse_flat_dt_reg(unsigned long node, const char *uname,
> +			 phys_addr_t *base, phys_addr_t *size);
> +int of_parse_flat_dt_size(unsigned long node, const char *uname,
> +			  phys_addr_t *size);
> +
> +#define RESERVEDMEM_OF_DECLARE(name, compat, init)			\
> +	static const struct of_device_id __reservedmem_of_table_##name	\
> +		__used __section(__reservedmem_of_table)		\
> +		 = { .compatible = compat,				\
> +		     .data = (init == (reservedmem_of_init_fn)NULL) ?	\
> +				init : init }

Clever type checking! I haven't known about doing it that way.

> +
> +#else
> +static inline void of_reserved_mem_device_init(struct device *dev) { }
> +
> +static inline
> +void of_reserved_mem_device_release(struct device *dev) { }
> +
> +static inline void early_init_dt_scan_reserved_mem(void) { }
> +
> +#define RESERVEDMEM_OF_DECLARE(name, compat, init)			\
> +	static const struct of_device_id __reservedmem_of_table_##name	\
> +		__attribute__((unused))					\
> +		 = { .compatible = compat,				\
> +		     .data = (init == (reservedmem_of_init_fn)NULL) ?	\
> +				init : init }
> +
> +#endif
> +
> +#endif /* __OF_RESERVED_MEM_H */
> -- 
> 1.7.9.5
> 


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

* Re: [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-05 11:05     ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-05 11:05 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linaro-mm-sig, devicetree, linux-doc
  Cc: Marek Szyprowski, Kyungmin Park, Benjamin Herrenschmidt,
	Arnd Bergmann, Michal Nazarewicz, Tomasz Figa, Sascha Hauer,
	Laura Abbott, Rob Herring, Olof Johansson, Pawel Moll,
	Mark Rutland, Stephen Warren, Ian Campbell, Tomasz Figa,
	Kumar Gala, Nishanth Peethambaran, Marc, Josh Cartwright

On Tue, 04 Feb 2014 13:09:29 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> This patch adds device tree support for contiguous and reserved memory
> regions defined in device tree.
> 
> Large memory blocks can be reliably reserved only during early boot.
> This must happen before the whole memory management subsystem is
> initialized, because we need to ensure that the given contiguous blocks
> are not yet allocated by kernel. Also it must happen before kernel
> mappings for the whole low memory are created, to ensure that there will
> be no mappings (for reserved blocks) or mapping with special properties
> can be created (for CMA blocks). This all happens before device tree
> structures are unflattened, so we need to get reserved memory layout
> directly from fdt.
> 
> Later, those reserved memory regions are assigned to devices on each
> device structure initialization.
> 
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Laura Abbott <lauraa@codeaurora.org>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> [joshc: rework to implement new DT binding, provide mechanism for
>  plugging in new reserved-memory node handlers via
>  RESERVEDMEM_OF_DECLARE]
> Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
> [mszyprow: little code cleanup]
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/of/Kconfig                |    6 +
>  drivers/of/Makefile               |    1 +
>  drivers/of/of_reserved_mem.c      |  219 +++++++++++++++++++++++++++++++++++++
>  drivers/of/platform.c             |    7 ++
>  include/asm-generic/vmlinux.lds.h |   11 ++
>  include/linux/of_reserved_mem.h   |   62 +++++++++++
>  6 files changed, 306 insertions(+)
>  create mode 100644 drivers/of/of_reserved_mem.c
>  create mode 100644 include/linux/of_reserved_mem.h
> 
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index c6973f101a3e..aba13df56f3a 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -75,4 +75,10 @@ config OF_MTD
>  	depends on MTD
>  	def_bool y
>  
> +config OF_RESERVED_MEM
> +	depends on HAVE_MEMBLOCK
> +	def_bool y
> +	help
> +	  Helpers to allow for reservation of memory regions
> +
>  endmenu # OF
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index efd05102c405..ed9660adad77 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
>  obj-$(CONFIG_OF_PCI)	+= of_pci.o
>  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
>  obj-$(CONFIG_OF_MTD)	+= of_mtd.o
> +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> new file mode 100644
> index 000000000000..f17cd56e68d9
> --- /dev/null
> +++ b/drivers/of/of_reserved_mem.c
> @@ -0,0 +1,219 @@
> +/*
> + * Device tree based initialization code for reserved memory.
> + *
> + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com
> + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
> + * Author: Josh Cartwright <joshc@codeaurora.org>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of the
> + * License or (at your optional) any later version of the license.
> + */
> +#include <linux/memblock.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/of_fdt.h>
> +#include <linux/of_platform.h>
> +#include <linux/mm.h>
> +#include <linux/sizes.h>
> +#include <linux/of_reserved_mem.h>
> +
> +#define MAX_RESERVED_REGIONS	16
> +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
> +static int reserved_mem_count;
> +
> +int __init of_parse_flat_dt_reg(unsigned long node, const char *uname,
> +				   phys_addr_t *base, phys_addr_t *size)

Useful utility function; move to drivers/of/fdt.c

> +{
> +	unsigned long len;
> +	__be32 *prop;
> +
> +	prop = of_get_flat_dt_prop(node, "reg", &len);
> +	if (!prop)
> +		return -EINVAL;
> +
> +	if (len < (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) {
> +		pr_err("Reserved memory: invalid reg property in '%s' node.\n",
> +				uname);
> +		return -EINVAL;
> +	}

This is /okay/ for an initial implementation, but it is naive. While I
suggested making #address-cells and #size-cells equal the root node
values for the purpose of simplicity, it should still be perfectly valid
to have different values if the ranges property is correctly formed.

> +
> +	*base = dt_mem_next_cell(dt_root_addr_cells, &prop);
> +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);

Future enhancement; allow for parsing more than just the first reg
tuple.

> +	return 0;
> +}

> +
> +int __init of_parse_flat_dt_size(unsigned long node, const char *uname,
> +				    phys_addr_t *size)
> +{
> +	unsigned long len;
> +	__be32 *prop;
> +
> +	prop = of_get_flat_dt_prop(node, "size", &len);
> +	if (!prop)
> +		return -EINVAL;
> +
> +	if (len < dt_root_size_cells * sizeof(__be32)) {
> +		pr_err("Reserved memory: invalid size property in '%s' node.\n",
> +				uname);
> +		return -EINVAL;
> +	}

More than that, the size should be dead on. '==' would be the correct
test I think.

> +
> +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
> +	return 0;
> +}
> +
> +static int __init rmem_default_early_setup(struct reserved_mem *rmem,
> +					   unsigned long node,
> +					   const char *uname)
> +{
> +	int err;
> +
> +	if (of_get_flat_dt_prop(node, "compatible", NULL))
> +		return -EINVAL;
> +
> +	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
> +	if (err)
> +		return err;
> +
> +	if (of_get_flat_dt_prop(node, "no-map", NULL))
> +		err = memblock_remove(rmem->base, rmem->size);
> +	else
> +		err = memblock_reserve(rmem->base, rmem->size);

This is the only dependency on memblock. Make it an arch hook, and
create a default __weak implementation:

#if defined(CONFIG_HAVE_MEMBLOCK)
int __init __weak early_init_dt_reserve_memory_arch(u64 base, u64 size, bool nomap)
{
	if (nomap)
		return memblock_remove(base, size);
	return memblock_reserve(base, size);
}
#else
int __init __weak early_init_dt_reserve_memory_arch(u64 base, u64 size, bool nomap)
{
	pr_error("Reserved memory not supported, ignoring range 0x%llx - 0x%llx%s\n",
		base, size, nomap ? " (nomap)" : "");
}
#endif

> +
> +	if (err == 0)
> +		pr_info("Reserved memory: found '%s', memory base %pa, size %ld MiB\n",
> +			uname, &rmem->base, (unsigned long)rmem->size / SZ_1M);

pr_info will be too chatty I think. pr_debug please.

> +
> +	return err;
> +}
> +
> +static const struct of_device_id rmem_default_id
> +	__used __section(__reservedmem_of_table_end) = {
> +	.data		= rmem_default_early_setup,
> +};

I was going to say this isn't very type safe and that the only reason to
use of_device_id is when using of_match_node() which will iterate a
table for you. But reading further I see you're handling type checking
in the macro so this is okay.

> +
> +static int __init fdt_scan_reserved_mem(unsigned long node, const char *uname,
> +					int depth, void *data)

Move this function to fdt.c. It should be treated as a fundamental part
of memory node parsing. It should also always be enabled, regardless of
the CONFIG_OF_RESERVED_MEMORY state because the region should always be
set aside even when the kernel doesn't know how to use it.

> +{
> +	struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
> +	extern const struct of_device_id __reservedmem_of_table[];
> +	const struct of_device_id *id;
> +	const char *status;
> +
> +	if (reserved_mem_count == ARRAY_SIZE(reserved_mem)) {
> +		pr_err("Reserved memory: not enough space all defined regions.\n");
> +		return -ENOSPC;
> +	}

It is not okay to bail here. If a region is reserved, then the kernel
*MUST* honor it, even if drivers cannot make use of it. As a bare
minimum it should be removed from the memblock pool.

> +
> +	status = of_get_flat_dt_prop(node, "status", NULL);
> +	if (status && strcmp(status, "okay") != 0)
> +		return 0;
> +
> +	/*
> +	 * The default handler above ensures this section is terminated with a
> +	 * id whose compatible string is empty
> +	 */
> +	for (id = __reservedmem_of_table; id <= &rmem_default_id; id++) {
> +		reservedmem_of_init_fn initfn = id->data;
> +		const char *compat = id->compatible;
> +
> +		if (compat[0] && !of_flat_dt_is_compatible(node, compat))
> +			continue;
> +
> +		if (initfn(rmem, node, uname) == 0) {
> +			pr_info("Reserved memory: created %s node, compatible id %s\n",
> +				uname, compat);
> +			rmem->name = uname;
> +			reserved_mem_count++;
> +			break;
> +		}
> +	}

What would be the condition that a special setup hook is called, but the
memory is not removed from the memblock pool? I seems wrong to me that
memory blocks wouldn't always get removed from main memory; even if
special setup code is executed on them.

By calling out to extra setup functions it means that each one of them
needs to implement its own memory removal code and get it correct. There
is a strong possibility for bugs there.

> +
> +	return 0;
> +}
> +
> +static struct reserved_mem *find_rmem(struct device_node *np)
> +{
> +	const char *name;
> +	unsigned int i;
> +
> +	name = kbasename(np->full_name);
> +
> +	for (i = 0; i < reserved_mem_count; i++)
> +		if (strcmp(name, reserved_mem[i].name) == 0)
> +			return &reserved_mem[i];

This looks fragile. It needs to match on the full path, not just
kbasename(), but that is expensive. However, all reserved regions should
have a phandle. You can use that for matching.

> +
> +	return NULL;
> +}
> +
> +/**
> + * of_reserved_mem_device_init() - assign reserved memory region to given device
> + *
> + * This function assign memory region pointed by "memory-region" device tree
> + * property to the given device.
> + */
> +void of_reserved_mem_device_init(struct device *dev)
> +{
> +	struct device_node *np = dev->of_node;
> +	struct reserved_mem *rmem;
> +	struct of_phandle_args s;
> +	unsigned int i;
> +
> +	for (i = 0; of_parse_phandle_with_args(np, "memory-region",
> +				"#memory-region-cells", i, &s) == 0; i++) {
> +
> +		rmem = find_rmem(s.np);
> +		if (!rmem || !rmem->ops || !rmem->ops->device_init) {
> +			of_node_put(s.np);
> +			continue;
> +		}
> +
> +		rmem->ops->device_init(rmem, dev, &s);
> +		dev_info(dev, "assigned reserved memory node %s\n",
> +			 rmem->name);
> +		of_node_put(s.np);
> +		break;
> +	}
> +}
> +
> +/**
> + * of_reserved_mem_device_release() - release reserved memory device structures
> + *
> + * This function releases structures allocated for memory region handling for
> + * the given device.
> + */
> +void of_reserved_mem_device_release(struct device *dev)
> +{
> +	struct device_node *np = dev->of_node;
> +	struct reserved_mem *rmem;
> +	struct of_phandle_args s;
> +	unsigned int i;
> +
> +	for (i = 0; of_parse_phandle_with_args(np, "memory-region",
> +				"#memory-region-cells", i, &s) == 0; i++) {
> +
> +		rmem = find_rmem(s.np);
> +		if (rmem && rmem->ops && rmem->ops->device_release)
> +			rmem->ops->device_release(rmem, dev);
> +
> +		of_node_put(s.np);
> +	}
> +}
> +
> +/**
> + * early_init_dt_scan_reserved_mem() - create reserved memory regions
> + *
> + * This function grabs memory from early allocator for device exclusive use
> + * defined in device tree structures. It should be called by arch specific code
> + * once the early allocator (memblock) has been activated and all other
> + * subsystems have already allocated/reserved memory.

As commented on patch 4, this should be called by common parsing code,
not arch code.

Why do you require other subsystems to allocate/reserve memory before
the reserved regions? I would think that the reserved regions declared
in the device tree would take precedence.

> + */
> +void __init early_init_dt_scan_reserved_mem(void)
> +{
> +	of_scan_flat_dt_by_path("/reserved-memory", fdt_scan_reserved_mem,
> +				NULL);
> +}
> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> index 404d1daebefa..3df0b1826e8b 100644
> --- a/drivers/of/platform.c
> +++ b/drivers/of/platform.c
> @@ -21,6 +21,7 @@
>  #include <linux/of_device.h>
>  #include <linux/of_irq.h>
>  #include <linux/of_platform.h>
> +#include <linux/of_reserved_mem.h>
>  #include <linux/platform_device.h>
>  
>  const struct of_device_id of_default_bus_match_table[] = {
> @@ -220,6 +221,8 @@ static struct platform_device *of_platform_device_create_pdata(
>  	dev->dev.bus = &platform_bus_type;
>  	dev->dev.platform_data = platform_data;
>  
> +	of_reserved_mem_device_init(&dev->dev);
> +
>  	/* We do not fill the DMA ops for platform devices by default.
>  	 * This is currently the responsibility of the platform code
>  	 * to do such, possibly using a device notifier
> @@ -227,6 +230,7 @@ static struct platform_device *of_platform_device_create_pdata(
>  
>  	if (of_device_add(dev) != 0) {
>  		platform_device_put(dev);
> +		of_reserved_mem_device_release(&dev->dev);
>  		return NULL;
>  	}
>  
> @@ -282,6 +286,8 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
>  	else
>  		of_device_make_bus_id(&dev->dev);
>  
> +	of_reserved_mem_device_init(&dev->dev);
> +
>  	/* Allow the HW Peripheral ID to be overridden */
>  	prop = of_get_property(node, "arm,primecell-periphid", NULL);
>  	if (prop)
> @@ -308,6 +314,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
>  	return dev;
>  
>  err_free:
> +	of_reserved_mem_device_release(&dev->dev);
>  	amba_device_put(dev);
>  	return NULL;
>  }
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index bc2121fa9132..f10f64fcc815 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -167,6 +167,16 @@
>  #define CLK_OF_TABLES()
>  #endif
>  
> +#ifdef CONFIG_OF_RESERVED_MEM
> +#define RESERVEDMEM_OF_TABLES()				\
> +	. = ALIGN(8);					\
> +	VMLINUX_SYMBOL(__reservedmem_of_table) = .;	\
> +	*(__reservedmem_of_table)			\
> +	*(__reservedmem_of_table_end)
> +#else
> +#define RESERVEDMEM_OF_TABLES()
> +#endif
> +
>  #define KERNEL_DTB()							\
>  	STRUCT_ALIGN();							\
>  	VMLINUX_SYMBOL(__dtb_start) = .;				\
> @@ -490,6 +500,7 @@
>  	TRACE_SYSCALLS()						\
>  	MEM_DISCARD(init.rodata)					\
>  	CLK_OF_TABLES()							\
> +	RESERVEDMEM_OF_TABLES()						\
>  	CLKSRC_OF_TABLES()						\
>  	KERNEL_DTB()							\
>  	IRQCHIP_OF_MATCH_TABLE()
> diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
> new file mode 100644
> index 000000000000..41f43828e1db
> --- /dev/null
> +++ b/include/linux/of_reserved_mem.h
> @@ -0,0 +1,62 @@
> +#ifndef __OF_RESERVED_MEM_H
> +#define __OF_RESERVED_MEM_H
> +
> +struct cma;
> +struct platform_device;
> +struct of_phandle_args;
> +struct reserved_mem_ops;
> +
> +struct reserved_mem {
> +	const char			*name;
> +	const struct reserved_mem_ops	*ops;
> +	phys_addr_t			base;
> +	phys_addr_t			size;
> +	void				*priv;
> +};
> +
> +struct reserved_mem_ops {
> +	void	(*device_init)(struct reserved_mem *rmem,
> +			       struct device *dev,
> +			       struct of_phandle_args *args);
> +	void	(*device_release)(struct reserved_mem *rmem,
> +				  struct device *dev);
> +};
> +
> +typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem,
> +				      unsigned long node, const char *uname);
> +
> +#ifdef CONFIG_OF_RESERVED_MEM
> +void of_reserved_mem_device_init(struct device *dev);
> +void of_reserved_mem_device_release(struct device *dev);
> +void early_init_dt_scan_reserved_mem(void);
> +
> +int of_parse_flat_dt_reg(unsigned long node, const char *uname,
> +			 phys_addr_t *base, phys_addr_t *size);
> +int of_parse_flat_dt_size(unsigned long node, const char *uname,
> +			  phys_addr_t *size);
> +
> +#define RESERVEDMEM_OF_DECLARE(name, compat, init)			\
> +	static const struct of_device_id __reservedmem_of_table_##name	\
> +		__used __section(__reservedmem_of_table)		\
> +		 = { .compatible = compat,				\
> +		     .data = (init == (reservedmem_of_init_fn)NULL) ?	\
> +				init : init }

Clever type checking! I haven't known about doing it that way.

> +
> +#else
> +static inline void of_reserved_mem_device_init(struct device *dev) { }
> +
> +static inline
> +void of_reserved_mem_device_release(struct device *dev) { }
> +
> +static inline void early_init_dt_scan_reserved_mem(void) { }
> +
> +#define RESERVEDMEM_OF_DECLARE(name, compat, init)			\
> +	static const struct of_device_id __reservedmem_of_table_##name	\
> +		__attribute__((unused))					\
> +		 = { .compatible = compat,				\
> +		     .data = (init == (reservedmem_of_init_fn)NULL) ?	\
> +				init : init }
> +
> +#endif
> +
> +#endif /* __OF_RESERVED_MEM_H */
> -- 
> 1.7.9.5
> 


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

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-05 11:05     ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-05 11:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 04 Feb 2014 13:09:29 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> This patch adds device tree support for contiguous and reserved memory
> regions defined in device tree.
> 
> Large memory blocks can be reliably reserved only during early boot.
> This must happen before the whole memory management subsystem is
> initialized, because we need to ensure that the given contiguous blocks
> are not yet allocated by kernel. Also it must happen before kernel
> mappings for the whole low memory are created, to ensure that there will
> be no mappings (for reserved blocks) or mapping with special properties
> can be created (for CMA blocks). This all happens before device tree
> structures are unflattened, so we need to get reserved memory layout
> directly from fdt.
> 
> Later, those reserved memory regions are assigned to devices on each
> device structure initialization.
> 
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Laura Abbott <lauraa@codeaurora.org>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> [joshc: rework to implement new DT binding, provide mechanism for
>  plugging in new reserved-memory node handlers via
>  RESERVEDMEM_OF_DECLARE]
> Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
> [mszyprow: little code cleanup]
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/of/Kconfig                |    6 +
>  drivers/of/Makefile               |    1 +
>  drivers/of/of_reserved_mem.c      |  219 +++++++++++++++++++++++++++++++++++++
>  drivers/of/platform.c             |    7 ++
>  include/asm-generic/vmlinux.lds.h |   11 ++
>  include/linux/of_reserved_mem.h   |   62 +++++++++++
>  6 files changed, 306 insertions(+)
>  create mode 100644 drivers/of/of_reserved_mem.c
>  create mode 100644 include/linux/of_reserved_mem.h
> 
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index c6973f101a3e..aba13df56f3a 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -75,4 +75,10 @@ config OF_MTD
>  	depends on MTD
>  	def_bool y
>  
> +config OF_RESERVED_MEM
> +	depends on HAVE_MEMBLOCK
> +	def_bool y
> +	help
> +	  Helpers to allow for reservation of memory regions
> +
>  endmenu # OF
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index efd05102c405..ed9660adad77 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
>  obj-$(CONFIG_OF_PCI)	+= of_pci.o
>  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
>  obj-$(CONFIG_OF_MTD)	+= of_mtd.o
> +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> new file mode 100644
> index 000000000000..f17cd56e68d9
> --- /dev/null
> +++ b/drivers/of/of_reserved_mem.c
> @@ -0,0 +1,219 @@
> +/*
> + * Device tree based initialization code for reserved memory.
> + *
> + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com
> + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
> + * Author: Josh Cartwright <joshc@codeaurora.org>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of the
> + * License or (at your optional) any later version of the license.
> + */
> +#include <linux/memblock.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/of_fdt.h>
> +#include <linux/of_platform.h>
> +#include <linux/mm.h>
> +#include <linux/sizes.h>
> +#include <linux/of_reserved_mem.h>
> +
> +#define MAX_RESERVED_REGIONS	16
> +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
> +static int reserved_mem_count;
> +
> +int __init of_parse_flat_dt_reg(unsigned long node, const char *uname,
> +				   phys_addr_t *base, phys_addr_t *size)

Useful utility function; move to drivers/of/fdt.c

> +{
> +	unsigned long len;
> +	__be32 *prop;
> +
> +	prop = of_get_flat_dt_prop(node, "reg", &len);
> +	if (!prop)
> +		return -EINVAL;
> +
> +	if (len < (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) {
> +		pr_err("Reserved memory: invalid reg property in '%s' node.\n",
> +				uname);
> +		return -EINVAL;
> +	}

This is /okay/ for an initial implementation, but it is naive. While I
suggested making #address-cells and #size-cells equal the root node
values for the purpose of simplicity, it should still be perfectly valid
to have different values if the ranges property is correctly formed.

> +
> +	*base = dt_mem_next_cell(dt_root_addr_cells, &prop);
> +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);

Future enhancement; allow for parsing more than just the first reg
tuple.

> +	return 0;
> +}

> +
> +int __init of_parse_flat_dt_size(unsigned long node, const char *uname,
> +				    phys_addr_t *size)
> +{
> +	unsigned long len;
> +	__be32 *prop;
> +
> +	prop = of_get_flat_dt_prop(node, "size", &len);
> +	if (!prop)
> +		return -EINVAL;
> +
> +	if (len < dt_root_size_cells * sizeof(__be32)) {
> +		pr_err("Reserved memory: invalid size property in '%s' node.\n",
> +				uname);
> +		return -EINVAL;
> +	}

More than that, the size should be dead on. '==' would be the correct
test I think.

> +
> +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
> +	return 0;
> +}
> +
> +static int __init rmem_default_early_setup(struct reserved_mem *rmem,
> +					   unsigned long node,
> +					   const char *uname)
> +{
> +	int err;
> +
> +	if (of_get_flat_dt_prop(node, "compatible", NULL))
> +		return -EINVAL;
> +
> +	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
> +	if (err)
> +		return err;
> +
> +	if (of_get_flat_dt_prop(node, "no-map", NULL))
> +		err = memblock_remove(rmem->base, rmem->size);
> +	else
> +		err = memblock_reserve(rmem->base, rmem->size);

This is the only dependency on memblock. Make it an arch hook, and
create a default __weak implementation:

#if defined(CONFIG_HAVE_MEMBLOCK)
int __init __weak early_init_dt_reserve_memory_arch(u64 base, u64 size, bool nomap)
{
	if (nomap)
		return memblock_remove(base, size);
	return memblock_reserve(base, size);
}
#else
int __init __weak early_init_dt_reserve_memory_arch(u64 base, u64 size, bool nomap)
{
	pr_error("Reserved memory not supported, ignoring range 0x%llx - 0x%llx%s\n",
		base, size, nomap ? " (nomap)" : "");
}
#endif

> +
> +	if (err == 0)
> +		pr_info("Reserved memory: found '%s', memory base %pa, size %ld MiB\n",
> +			uname, &rmem->base, (unsigned long)rmem->size / SZ_1M);

pr_info will be too chatty I think. pr_debug please.

> +
> +	return err;
> +}
> +
> +static const struct of_device_id rmem_default_id
> +	__used __section(__reservedmem_of_table_end) = {
> +	.data		= rmem_default_early_setup,
> +};

I was going to say this isn't very type safe and that the only reason to
use of_device_id is when using of_match_node() which will iterate a
table for you. But reading further I see you're handling type checking
in the macro so this is okay.

> +
> +static int __init fdt_scan_reserved_mem(unsigned long node, const char *uname,
> +					int depth, void *data)

Move this function to fdt.c. It should be treated as a fundamental part
of memory node parsing. It should also always be enabled, regardless of
the CONFIG_OF_RESERVED_MEMORY state because the region should always be
set aside even when the kernel doesn't know how to use it.

> +{
> +	struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
> +	extern const struct of_device_id __reservedmem_of_table[];
> +	const struct of_device_id *id;
> +	const char *status;
> +
> +	if (reserved_mem_count == ARRAY_SIZE(reserved_mem)) {
> +		pr_err("Reserved memory: not enough space all defined regions.\n");
> +		return -ENOSPC;
> +	}

It is not okay to bail here. If a region is reserved, then the kernel
*MUST* honor it, even if drivers cannot make use of it. As a bare
minimum it should be removed from the memblock pool.

> +
> +	status = of_get_flat_dt_prop(node, "status", NULL);
> +	if (status && strcmp(status, "okay") != 0)
> +		return 0;
> +
> +	/*
> +	 * The default handler above ensures this section is terminated with a
> +	 * id whose compatible string is empty
> +	 */
> +	for (id = __reservedmem_of_table; id <= &rmem_default_id; id++) {
> +		reservedmem_of_init_fn initfn = id->data;
> +		const char *compat = id->compatible;
> +
> +		if (compat[0] && !of_flat_dt_is_compatible(node, compat))
> +			continue;
> +
> +		if (initfn(rmem, node, uname) == 0) {
> +			pr_info("Reserved memory: created %s node, compatible id %s\n",
> +				uname, compat);
> +			rmem->name = uname;
> +			reserved_mem_count++;
> +			break;
> +		}
> +	}

What would be the condition that a special setup hook is called, but the
memory is not removed from the memblock pool? I seems wrong to me that
memory blocks wouldn't always get removed from main memory; even if
special setup code is executed on them.

By calling out to extra setup functions it means that each one of them
needs to implement its own memory removal code and get it correct. There
is a strong possibility for bugs there.

> +
> +	return 0;
> +}
> +
> +static struct reserved_mem *find_rmem(struct device_node *np)
> +{
> +	const char *name;
> +	unsigned int i;
> +
> +	name = kbasename(np->full_name);
> +
> +	for (i = 0; i < reserved_mem_count; i++)
> +		if (strcmp(name, reserved_mem[i].name) == 0)
> +			return &reserved_mem[i];

This looks fragile. It needs to match on the full path, not just
kbasename(), but that is expensive. However, all reserved regions should
have a phandle. You can use that for matching.

> +
> +	return NULL;
> +}
> +
> +/**
> + * of_reserved_mem_device_init() - assign reserved memory region to given device
> + *
> + * This function assign memory region pointed by "memory-region" device tree
> + * property to the given device.
> + */
> +void of_reserved_mem_device_init(struct device *dev)
> +{
> +	struct device_node *np = dev->of_node;
> +	struct reserved_mem *rmem;
> +	struct of_phandle_args s;
> +	unsigned int i;
> +
> +	for (i = 0; of_parse_phandle_with_args(np, "memory-region",
> +				"#memory-region-cells", i, &s) == 0; i++) {
> +
> +		rmem = find_rmem(s.np);
> +		if (!rmem || !rmem->ops || !rmem->ops->device_init) {
> +			of_node_put(s.np);
> +			continue;
> +		}
> +
> +		rmem->ops->device_init(rmem, dev, &s);
> +		dev_info(dev, "assigned reserved memory node %s\n",
> +			 rmem->name);
> +		of_node_put(s.np);
> +		break;
> +	}
> +}
> +
> +/**
> + * of_reserved_mem_device_release() - release reserved memory device structures
> + *
> + * This function releases structures allocated for memory region handling for
> + * the given device.
> + */
> +void of_reserved_mem_device_release(struct device *dev)
> +{
> +	struct device_node *np = dev->of_node;
> +	struct reserved_mem *rmem;
> +	struct of_phandle_args s;
> +	unsigned int i;
> +
> +	for (i = 0; of_parse_phandle_with_args(np, "memory-region",
> +				"#memory-region-cells", i, &s) == 0; i++) {
> +
> +		rmem = find_rmem(s.np);
> +		if (rmem && rmem->ops && rmem->ops->device_release)
> +			rmem->ops->device_release(rmem, dev);
> +
> +		of_node_put(s.np);
> +	}
> +}
> +
> +/**
> + * early_init_dt_scan_reserved_mem() - create reserved memory regions
> + *
> + * This function grabs memory from early allocator for device exclusive use
> + * defined in device tree structures. It should be called by arch specific code
> + * once the early allocator (memblock) has been activated and all other
> + * subsystems have already allocated/reserved memory.

As commented on patch 4, this should be called by common parsing code,
not arch code.

Why do you require other subsystems to allocate/reserve memory before
the reserved regions? I would think that the reserved regions declared
in the device tree would take precedence.

> + */
> +void __init early_init_dt_scan_reserved_mem(void)
> +{
> +	of_scan_flat_dt_by_path("/reserved-memory", fdt_scan_reserved_mem,
> +				NULL);
> +}
> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> index 404d1daebefa..3df0b1826e8b 100644
> --- a/drivers/of/platform.c
> +++ b/drivers/of/platform.c
> @@ -21,6 +21,7 @@
>  #include <linux/of_device.h>
>  #include <linux/of_irq.h>
>  #include <linux/of_platform.h>
> +#include <linux/of_reserved_mem.h>
>  #include <linux/platform_device.h>
>  
>  const struct of_device_id of_default_bus_match_table[] = {
> @@ -220,6 +221,8 @@ static struct platform_device *of_platform_device_create_pdata(
>  	dev->dev.bus = &platform_bus_type;
>  	dev->dev.platform_data = platform_data;
>  
> +	of_reserved_mem_device_init(&dev->dev);
> +
>  	/* We do not fill the DMA ops for platform devices by default.
>  	 * This is currently the responsibility of the platform code
>  	 * to do such, possibly using a device notifier
> @@ -227,6 +230,7 @@ static struct platform_device *of_platform_device_create_pdata(
>  
>  	if (of_device_add(dev) != 0) {
>  		platform_device_put(dev);
> +		of_reserved_mem_device_release(&dev->dev);
>  		return NULL;
>  	}
>  
> @@ -282,6 +286,8 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
>  	else
>  		of_device_make_bus_id(&dev->dev);
>  
> +	of_reserved_mem_device_init(&dev->dev);
> +
>  	/* Allow the HW Peripheral ID to be overridden */
>  	prop = of_get_property(node, "arm,primecell-periphid", NULL);
>  	if (prop)
> @@ -308,6 +314,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
>  	return dev;
>  
>  err_free:
> +	of_reserved_mem_device_release(&dev->dev);
>  	amba_device_put(dev);
>  	return NULL;
>  }
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index bc2121fa9132..f10f64fcc815 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -167,6 +167,16 @@
>  #define CLK_OF_TABLES()
>  #endif
>  
> +#ifdef CONFIG_OF_RESERVED_MEM
> +#define RESERVEDMEM_OF_TABLES()				\
> +	. = ALIGN(8);					\
> +	VMLINUX_SYMBOL(__reservedmem_of_table) = .;	\
> +	*(__reservedmem_of_table)			\
> +	*(__reservedmem_of_table_end)
> +#else
> +#define RESERVEDMEM_OF_TABLES()
> +#endif
> +
>  #define KERNEL_DTB()							\
>  	STRUCT_ALIGN();							\
>  	VMLINUX_SYMBOL(__dtb_start) = .;				\
> @@ -490,6 +500,7 @@
>  	TRACE_SYSCALLS()						\
>  	MEM_DISCARD(init.rodata)					\
>  	CLK_OF_TABLES()							\
> +	RESERVEDMEM_OF_TABLES()						\
>  	CLKSRC_OF_TABLES()						\
>  	KERNEL_DTB()							\
>  	IRQCHIP_OF_MATCH_TABLE()
> diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
> new file mode 100644
> index 000000000000..41f43828e1db
> --- /dev/null
> +++ b/include/linux/of_reserved_mem.h
> @@ -0,0 +1,62 @@
> +#ifndef __OF_RESERVED_MEM_H
> +#define __OF_RESERVED_MEM_H
> +
> +struct cma;
> +struct platform_device;
> +struct of_phandle_args;
> +struct reserved_mem_ops;
> +
> +struct reserved_mem {
> +	const char			*name;
> +	const struct reserved_mem_ops	*ops;
> +	phys_addr_t			base;
> +	phys_addr_t			size;
> +	void				*priv;
> +};
> +
> +struct reserved_mem_ops {
> +	void	(*device_init)(struct reserved_mem *rmem,
> +			       struct device *dev,
> +			       struct of_phandle_args *args);
> +	void	(*device_release)(struct reserved_mem *rmem,
> +				  struct device *dev);
> +};
> +
> +typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem,
> +				      unsigned long node, const char *uname);
> +
> +#ifdef CONFIG_OF_RESERVED_MEM
> +void of_reserved_mem_device_init(struct device *dev);
> +void of_reserved_mem_device_release(struct device *dev);
> +void early_init_dt_scan_reserved_mem(void);
> +
> +int of_parse_flat_dt_reg(unsigned long node, const char *uname,
> +			 phys_addr_t *base, phys_addr_t *size);
> +int of_parse_flat_dt_size(unsigned long node, const char *uname,
> +			  phys_addr_t *size);
> +
> +#define RESERVEDMEM_OF_DECLARE(name, compat, init)			\
> +	static const struct of_device_id __reservedmem_of_table_##name	\
> +		__used __section(__reservedmem_of_table)		\
> +		 = { .compatible = compat,				\
> +		     .data = (init == (reservedmem_of_init_fn)NULL) ?	\
> +				init : init }

Clever type checking! I haven't known about doing it that way.

> +
> +#else
> +static inline void of_reserved_mem_device_init(struct device *dev) { }
> +
> +static inline
> +void of_reserved_mem_device_release(struct device *dev) { }
> +
> +static inline void early_init_dt_scan_reserved_mem(void) { }
> +
> +#define RESERVEDMEM_OF_DECLARE(name, compat, init)			\
> +	static const struct of_device_id __reservedmem_of_table_##name	\
> +		__attribute__((unused))					\
> +		 = { .compatible = compat,				\
> +		     .data = (init == (reservedmem_of_init_fn)NULL) ?	\
> +				init : init }
> +
> +#endif
> +
> +#endif /* __OF_RESERVED_MEM_H */
> -- 
> 1.7.9.5
> 

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

* Re: [PATCH v2 3/5] drivers: of: implement reserved-memory handling for cma
  2014-02-04 12:09   ` Marek Szyprowski
  (?)
@ 2014-02-05 11:09     ` Grant Likely
  -1 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-05 11:09 UTC (permalink / raw)
  To: Marek Szyprowski, linux-kernel, linux-arm-kernel, linaro-mm-sig,
	devicetree, linux-doc
  Cc: Marek Szyprowski, Kyungmin Park, Benjamin Herrenschmidt,
	Arnd Bergmann, Michal Nazarewicz, Tomasz Figa, Sascha Hauer,
	Laura Abbott, Rob Herring, Olof Johansson, Pawel Moll,
	Mark Rutland, Stephen Warren, Ian Campbell, Tomasz Figa,
	Kumar Gala, Nishanth Peethambaran, Marc, Josh Cartwright

On Tue, 04 Feb 2014 13:09:31 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> From: Josh Cartwright <joshc@codeaurora.org>
> 
> Add support for handling 'shared-dma-pool' reserved-memory nodes using
> Contiguous Memory Allocator driver.
> 
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Laura Abbott <lauraa@codeaurora.org>
> Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/of/Kconfig               |    7 ++++
>  drivers/of/Makefile              |    1 +
>  drivers/of/of_reserved_mem_cma.c |   75 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 83 insertions(+)
>  create mode 100644 drivers/of/of_reserved_mem_cma.c
> 
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index 7ac330473ec9..5dd3a80910d2 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -81,6 +81,13 @@ config OF_RESERVED_MEM
>  	help
>  	  Helpers to allow for reservation of memory regions
>  
> +config OF_RESERVED_MEM_CMA
> +	depends on OF_RESERVED_MEM
> +	depends on DMA_CMA
> +	def_bool y
> +	help
> +	  Helpers for reserving memory regions for DMA use
> +
>  config OF_RESERVED_MEM_DMA
>  	depends on OF_RESERVED_MEM
>  	depends on HAVE_GENERIC_DMA_COHERENT
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index 6142227ca854..49b9078637b8 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -10,4 +10,5 @@ obj-$(CONFIG_OF_PCI)	+= of_pci.o
>  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
>  obj-$(CONFIG_OF_MTD)	+= of_mtd.o
>  obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> +obj-$(CONFIG_OF_RESERVED_MEM_CMA) += of_reserved_mem_cma.o
>  obj-$(CONFIG_OF_RESERVED_MEM_DMA) += of_reserved_mem_dma.o
> diff --git a/drivers/of/of_reserved_mem_cma.c b/drivers/of/of_reserved_mem_cma.c
> new file mode 100644
> index 000000000000..601d80655102
> --- /dev/null
> +++ b/drivers/of/of_reserved_mem_cma.c
> @@ -0,0 +1,75 @@
> +/*
> + * Device tree based initialization code for DMA reserved regions.
> + *
> + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com
> + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
> + * Author: Josh Cartwright <joshc@codeaurora.org>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of the
> + * License or (at your optional) any later version of the license.
> + */
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/of_fdt.h>
> +#include <linux/of_platform.h>
> +#include <linux/mm.h>
> +#include <linux/sizes.h>
> +#include <linux/mm_types.h>
> +#include <linux/dma-contiguous.h>
> +#include <linux/of_reserved_mem.h>
> +
> +static void rmem_cma_device_init(struct reserved_mem *rmem,
> +				 struct device *dev,
> +				 struct of_phandle_args *args)
> +{
> +	struct cma *cma = rmem->priv;
> +	dev_set_cma_area(dev, cma);
> +}
> +
> +static const struct reserved_mem_ops rmem_cma_ops = {
> +	.device_init	= rmem_cma_device_init,
> +};
> +
> +static int __init rmem_cma_setup(struct reserved_mem *rmem,
> +				 unsigned long node,
> +				 const char *uname)
> +{
> +	struct cma *cma;
> +	int err;
> +
> +	if (!of_get_flat_dt_prop(node, "reusable", NULL))
> +		return -EINVAL;
> +
> +	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
> +	if (!err)
> +		goto out_done;
> +
> +	rmem->base = 0;
> +	err = of_parse_flat_dt_size(node, uname, &rmem->size);
> +	if (err)
> +		goto out_err;
> +
> +out_done:

Please restrict gotos for error handling. Why not the following:

	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
	if (err) {
		rmem->base = 0;
		err = of_parse_flat_dt_size(node, uname, &rmem->size);
		if (err)
			goto out_err;
	}

> +	err = dma_contiguous_reserve_area(rmem->size, rmem->base, 0,
> +					  &cma);
> +	if (err) {
> +		pr_err("Reserved memory: unable to setup CMA region\n");
> +		return err;
> +	}
> +
> +	if (of_get_flat_dt_prop(node, "linux,cma-default", NULL))
> +		dma_contiguous_set_default(cma);
> +
> +	rmem->ops = &rmem_cma_ops;
> +	rmem->priv = cma;
> +
> +	return 0;
> +out_err:
> +	pr_err("Reseved memory: malformed node '%s'.\n", uname);
> +	return err;
> +}
> +RESERVEDMEM_OF_DECLARE(cma, "shared-dma-pool", rmem_cma_setup);
> -- 
> 1.7.9.5
> 


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

* Re: [PATCH v2 3/5] drivers: of: implement reserved-memory handling for cma
@ 2014-02-05 11:09     ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-05 11:09 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, linaro-mm-sig, devicetree, linux-doc
  Cc: Marek Szyprowski, Kyungmin Park, Benjamin Herrenschmidt,
	Arnd Bergmann, Michal Nazarewicz, Tomasz Figa, Sascha Hauer,
	Laura Abbott, Rob Herring, Olof Johansson, Pawel Moll,
	Mark Rutland, Stephen Warren, Ian Campbell, Tomasz Figa,
	Kumar Gala, Nishanth Peethambaran, Marc, Josh Cartwright

On Tue, 04 Feb 2014 13:09:31 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> From: Josh Cartwright <joshc@codeaurora.org>
> 
> Add support for handling 'shared-dma-pool' reserved-memory nodes using
> Contiguous Memory Allocator driver.
> 
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Laura Abbott <lauraa@codeaurora.org>
> Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/of/Kconfig               |    7 ++++
>  drivers/of/Makefile              |    1 +
>  drivers/of/of_reserved_mem_cma.c |   75 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 83 insertions(+)
>  create mode 100644 drivers/of/of_reserved_mem_cma.c
> 
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index 7ac330473ec9..5dd3a80910d2 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -81,6 +81,13 @@ config OF_RESERVED_MEM
>  	help
>  	  Helpers to allow for reservation of memory regions
>  
> +config OF_RESERVED_MEM_CMA
> +	depends on OF_RESERVED_MEM
> +	depends on DMA_CMA
> +	def_bool y
> +	help
> +	  Helpers for reserving memory regions for DMA use
> +
>  config OF_RESERVED_MEM_DMA
>  	depends on OF_RESERVED_MEM
>  	depends on HAVE_GENERIC_DMA_COHERENT
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index 6142227ca854..49b9078637b8 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -10,4 +10,5 @@ obj-$(CONFIG_OF_PCI)	+= of_pci.o
>  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
>  obj-$(CONFIG_OF_MTD)	+= of_mtd.o
>  obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> +obj-$(CONFIG_OF_RESERVED_MEM_CMA) += of_reserved_mem_cma.o
>  obj-$(CONFIG_OF_RESERVED_MEM_DMA) += of_reserved_mem_dma.o
> diff --git a/drivers/of/of_reserved_mem_cma.c b/drivers/of/of_reserved_mem_cma.c
> new file mode 100644
> index 000000000000..601d80655102
> --- /dev/null
> +++ b/drivers/of/of_reserved_mem_cma.c
> @@ -0,0 +1,75 @@
> +/*
> + * Device tree based initialization code for DMA reserved regions.
> + *
> + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com
> + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
> + * Author: Josh Cartwright <joshc@codeaurora.org>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of the
> + * License or (at your optional) any later version of the license.
> + */
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/of_fdt.h>
> +#include <linux/of_platform.h>
> +#include <linux/mm.h>
> +#include <linux/sizes.h>
> +#include <linux/mm_types.h>
> +#include <linux/dma-contiguous.h>
> +#include <linux/of_reserved_mem.h>
> +
> +static void rmem_cma_device_init(struct reserved_mem *rmem,
> +				 struct device *dev,
> +				 struct of_phandle_args *args)
> +{
> +	struct cma *cma = rmem->priv;
> +	dev_set_cma_area(dev, cma);
> +}
> +
> +static const struct reserved_mem_ops rmem_cma_ops = {
> +	.device_init	= rmem_cma_device_init,
> +};
> +
> +static int __init rmem_cma_setup(struct reserved_mem *rmem,
> +				 unsigned long node,
> +				 const char *uname)
> +{
> +	struct cma *cma;
> +	int err;
> +
> +	if (!of_get_flat_dt_prop(node, "reusable", NULL))
> +		return -EINVAL;
> +
> +	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
> +	if (!err)
> +		goto out_done;
> +
> +	rmem->base = 0;
> +	err = of_parse_flat_dt_size(node, uname, &rmem->size);
> +	if (err)
> +		goto out_err;
> +
> +out_done:

Please restrict gotos for error handling. Why not the following:

	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
	if (err) {
		rmem->base = 0;
		err = of_parse_flat_dt_size(node, uname, &rmem->size);
		if (err)
			goto out_err;
	}

> +	err = dma_contiguous_reserve_area(rmem->size, rmem->base, 0,
> +					  &cma);
> +	if (err) {
> +		pr_err("Reserved memory: unable to setup CMA region\n");
> +		return err;
> +	}
> +
> +	if (of_get_flat_dt_prop(node, "linux,cma-default", NULL))
> +		dma_contiguous_set_default(cma);
> +
> +	rmem->ops = &rmem_cma_ops;
> +	rmem->priv = cma;
> +
> +	return 0;
> +out_err:
> +	pr_err("Reseved memory: malformed node '%s'.\n", uname);
> +	return err;
> +}
> +RESERVEDMEM_OF_DECLARE(cma, "shared-dma-pool", rmem_cma_setup);
> -- 
> 1.7.9.5
> 


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

* [PATCH v2 3/5] drivers: of: implement reserved-memory handling for cma
@ 2014-02-05 11:09     ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-05 11:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 04 Feb 2014 13:09:31 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> From: Josh Cartwright <joshc@codeaurora.org>
> 
> Add support for handling 'shared-dma-pool' reserved-memory nodes using
> Contiguous Memory Allocator driver.
> 
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Laura Abbott <lauraa@codeaurora.org>
> Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/of/Kconfig               |    7 ++++
>  drivers/of/Makefile              |    1 +
>  drivers/of/of_reserved_mem_cma.c |   75 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 83 insertions(+)
>  create mode 100644 drivers/of/of_reserved_mem_cma.c
> 
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index 7ac330473ec9..5dd3a80910d2 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -81,6 +81,13 @@ config OF_RESERVED_MEM
>  	help
>  	  Helpers to allow for reservation of memory regions
>  
> +config OF_RESERVED_MEM_CMA
> +	depends on OF_RESERVED_MEM
> +	depends on DMA_CMA
> +	def_bool y
> +	help
> +	  Helpers for reserving memory regions for DMA use
> +
>  config OF_RESERVED_MEM_DMA
>  	depends on OF_RESERVED_MEM
>  	depends on HAVE_GENERIC_DMA_COHERENT
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index 6142227ca854..49b9078637b8 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -10,4 +10,5 @@ obj-$(CONFIG_OF_PCI)	+= of_pci.o
>  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
>  obj-$(CONFIG_OF_MTD)	+= of_mtd.o
>  obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> +obj-$(CONFIG_OF_RESERVED_MEM_CMA) += of_reserved_mem_cma.o
>  obj-$(CONFIG_OF_RESERVED_MEM_DMA) += of_reserved_mem_dma.o
> diff --git a/drivers/of/of_reserved_mem_cma.c b/drivers/of/of_reserved_mem_cma.c
> new file mode 100644
> index 000000000000..601d80655102
> --- /dev/null
> +++ b/drivers/of/of_reserved_mem_cma.c
> @@ -0,0 +1,75 @@
> +/*
> + * Device tree based initialization code for DMA reserved regions.
> + *
> + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com
> + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
> + * Author: Josh Cartwright <joshc@codeaurora.org>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of the
> + * License or (at your optional) any later version of the license.
> + */
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/of_fdt.h>
> +#include <linux/of_platform.h>
> +#include <linux/mm.h>
> +#include <linux/sizes.h>
> +#include <linux/mm_types.h>
> +#include <linux/dma-contiguous.h>
> +#include <linux/of_reserved_mem.h>
> +
> +static void rmem_cma_device_init(struct reserved_mem *rmem,
> +				 struct device *dev,
> +				 struct of_phandle_args *args)
> +{
> +	struct cma *cma = rmem->priv;
> +	dev_set_cma_area(dev, cma);
> +}
> +
> +static const struct reserved_mem_ops rmem_cma_ops = {
> +	.device_init	= rmem_cma_device_init,
> +};
> +
> +static int __init rmem_cma_setup(struct reserved_mem *rmem,
> +				 unsigned long node,
> +				 const char *uname)
> +{
> +	struct cma *cma;
> +	int err;
> +
> +	if (!of_get_flat_dt_prop(node, "reusable", NULL))
> +		return -EINVAL;
> +
> +	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
> +	if (!err)
> +		goto out_done;
> +
> +	rmem->base = 0;
> +	err = of_parse_flat_dt_size(node, uname, &rmem->size);
> +	if (err)
> +		goto out_err;
> +
> +out_done:

Please restrict gotos for error handling. Why not the following:

	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
	if (err) {
		rmem->base = 0;
		err = of_parse_flat_dt_size(node, uname, &rmem->size);
		if (err)
			goto out_err;
	}

> +	err = dma_contiguous_reserve_area(rmem->size, rmem->base, 0,
> +					  &cma);
> +	if (err) {
> +		pr_err("Reserved memory: unable to setup CMA region\n");
> +		return err;
> +	}
> +
> +	if (of_get_flat_dt_prop(node, "linux,cma-default", NULL))
> +		dma_contiguous_set_default(cma);
> +
> +	rmem->ops = &rmem_cma_ops;
> +	rmem->priv = cma;
> +
> +	return 0;
> +out_err:
> +	pr_err("Reseved memory: malformed node '%s'.\n", uname);
> +	return err;
> +}
> +RESERVEDMEM_OF_DECLARE(cma, "shared-dma-pool", rmem_cma_setup);
> -- 
> 1.7.9.5
> 

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

* Re: [PATCH v2 5/5] of: document bindings for reserved-memory nodes
  2014-02-05 10:07     ` Grant Likely
@ 2014-02-05 19:25       ` Josh Cartwright
  -1 siblings, 0 replies; 60+ messages in thread
From: Josh Cartwright @ 2014-02-05 19:25 UTC (permalink / raw)
  To: Grant Likely
  Cc: Marek Szyprowski, linux-kernel, linux-arm-kernel, linaro-mm-sig,
	devicetree, linux-doc, Kyungmin Park, Benjamin Herrenschmidt,
	Arnd Bergmann, Michal Nazarewicz, Tomasz Figa, Sascha Hauer,
	Laura Abbott, Rob Herring, Olof Johansson, Pawel Moll,
	Mark Rutland, Stephen Warren, Ian Campbell, Tomasz Figa,
	Kumar Gala, Nishanth Peethambaran, Marc

On Wed, Feb 05, 2014 at 10:07:50AM +0000, Grant Likely wrote:
> On Tue, 04 Feb 2014 13:09:33 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > From: Grant Likely <grant.likely@linaro.org>
> > +/reserved-memory node
> > +---------------------
> > +#address-cells, #size-cells (required) - standard definition
> > +    - Should use the same values as the root node
> > +#memory-region-cells (required) - dictates number of cells used in the child
> > +                                  nodes memory-region specifier
>
> I don't think this isn't defined well enough. These reserved regions may
> not have a driver attached to them, so there is no central agent to
> decide what the specifier means. That leaves the interpretation of
> the memory region in the hands of the client drivers. How do you see the
> specifier getting parsed and used?

I had a specific usecase in mind when I added it, although admittedly I
haven't yet worked through all of the details.

On MSM chips, there is a region of memory accessible from the various
processors on the SoC.  This region is used for (among other things)
inter-processor communication.  Inside this region, a heap allocation
protocol is implemented by software on all interested processors.

Consumers of this shared memory heap specify a 32-bit identifier and a
size, and are either given a matching preexisting chunk (for example,
another processor has already allocated a chunk with the corresponding
identifier), or are allocated a new chunk for that identifier out of the
region.

Given it's shared nature, this region has some specific requirements
about how it may be accessed by the kernel (specifically regarding
cacheability/how it's mapped), which means it at least needs _some_
representation in a reserved-memory node.

I had envisioned expressing the shared memory/consumer relationship in
the device tree:

	reserved-memory {
		smem : smem {
			compatible = "qcom,shared-memory";
			reg = <...>;
			#memory-region-cells = <2>;
			no-map;
		};
	};

	consumer {
		/* ... */;
		memory-region = <&smem 0xDEADBEEF 0x1000>;
	};

That is, the heap protocol implementation exists as a "driver" for the
smem reserved-memory node, and the consumer's 2-cell specifier is a
32-bit identifier and a size.

If your concern is for the case where a "qcom,shared-memory" node is
specified in a device tree, but the "driver" hasn't been built into the
kernel, then the appropriate behavior would be the same as the DMA/CMA
case: fallback to a default case of memblock_reserve/memblock_remove'ing
the region.

Would using reserved-memory in this way be outside the scope of what was
originally intended?

Thanks,
  Josh

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* [PATCH v2 5/5] of: document bindings for reserved-memory nodes
@ 2014-02-05 19:25       ` Josh Cartwright
  0 siblings, 0 replies; 60+ messages in thread
From: Josh Cartwright @ 2014-02-05 19:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 05, 2014 at 10:07:50AM +0000, Grant Likely wrote:
> On Tue, 04 Feb 2014 13:09:33 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > From: Grant Likely <grant.likely@linaro.org>
> > +/reserved-memory node
> > +---------------------
> > +#address-cells, #size-cells (required) - standard definition
> > +    - Should use the same values as the root node
> > +#memory-region-cells (required) - dictates number of cells used in the child
> > +                                  nodes memory-region specifier
>
> I don't think this isn't defined well enough. These reserved regions may
> not have a driver attached to them, so there is no central agent to
> decide what the specifier means. That leaves the interpretation of
> the memory region in the hands of the client drivers. How do you see the
> specifier getting parsed and used?

I had a specific usecase in mind when I added it, although admittedly I
haven't yet worked through all of the details.

On MSM chips, there is a region of memory accessible from the various
processors on the SoC.  This region is used for (among other things)
inter-processor communication.  Inside this region, a heap allocation
protocol is implemented by software on all interested processors.

Consumers of this shared memory heap specify a 32-bit identifier and a
size, and are either given a matching preexisting chunk (for example,
another processor has already allocated a chunk with the corresponding
identifier), or are allocated a new chunk for that identifier out of the
region.

Given it's shared nature, this region has some specific requirements
about how it may be accessed by the kernel (specifically regarding
cacheability/how it's mapped), which means it at least needs _some_
representation in a reserved-memory node.

I had envisioned expressing the shared memory/consumer relationship in
the device tree:

	reserved-memory {
		smem : smem {
			compatible = "qcom,shared-memory";
			reg = <...>;
			#memory-region-cells = <2>;
			no-map;
		};
	};

	consumer {
		/* ... */;
		memory-region = <&smem 0xDEADBEEF 0x1000>;
	};

That is, the heap protocol implementation exists as a "driver" for the
smem reserved-memory node, and the consumer's 2-cell specifier is a
32-bit identifier and a size.

If your concern is for the case where a "qcom,shared-memory" node is
specified in a device tree, but the "driver" hasn't been built into the
kernel, then the appropriate behavior would be the same as the DMA/CMA
case: fallback to a default case of memblock_reserve/memblock_remove'ing
the region.

Would using reserved-memory in this way be outside the scope of what was
originally intended?

Thanks,
  Josh

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* Re: [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
  2014-02-05 10:15     ` Grant Likely
@ 2014-02-06 13:26       ` Marek Szyprowski
  -1 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-06 13:26 UTC (permalink / raw)
  To: Grant Likely, linux-kernel, linux-arm-kernel, linaro-mm-sig,
	devicetree, linux-doc
  Cc: Kyungmin Park, Benjamin Herrenschmidt, Arnd Bergmann,
	Michal Nazarewicz, Tomasz Figa, Sascha Hauer, Laura Abbott,
	Rob Herring, Olof Johansson, Pawel Moll, Mark Rutland,
	Stephen Warren, Ian Campbell, Tomasz Figa, Kumar Gala,
	Nishanth Peethambaran, Marc, Josh Cartwright

Hello,

On 2014-02-05 11:15, Grant Likely wrote:
> On Tue, 04 Feb 2014 13:09:32 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > Enable reserved memory initialization from device tree.
> >
> > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Cc: Laura Abbott <lauraa@codeaurora.org>
> > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > ---
> >  arch/arm/mm/init.c |    3 +++
> >  1 file changed, 3 insertions(+)
> >
> > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> > index 804d61566a53..ebafdb479410 100644
> > --- a/arch/arm/mm/init.c
> > +++ b/arch/arm/mm/init.c
> > @@ -17,6 +17,7 @@
> >  #include <linux/nodemask.h>
> >  #include <linux/initrd.h>
> >  #include <linux/of_fdt.h>
> > +#include <linux/of_reserved_mem.h>
> >  #include <linux/highmem.h>
> >  #include <linux/gfp.h>
> >  #include <linux/memblock.h>
> > @@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
> >  	if (mdesc->reserve)
> >  		mdesc->reserve();
> >
> > +	early_init_dt_scan_reserved_mem();
> > +
>
> The new binding is being made fundamental. If the reserved-memory node
> is present, then it needs to be honored, even if the kernel doesn't know
> how to use the regions. Therefore, This needs to be unconditional for
> all architectures. The hook should be called in early_init_dt_scan()
> (drivers/of/fdt.c) immediately after the early_init_dt_scan_memory()
> hook.

In theory this will be the best solution, but it practice there is a
problem. early_init_dt_scan() is called as the first function from kernel
booting code. That time there is no memory yet added to the system, so it
would be really hard to reserve anything. Memory nodes are being added
later either with memblock_add() or by some other arch specific way.

Finally, once all memory has been added to the system we can parse and
reserve all regions defined in the device tree. This really requires
creating another function which will be called by arch specific code.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


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

* [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
@ 2014-02-06 13:26       ` Marek Szyprowski
  0 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-06 13:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On 2014-02-05 11:15, Grant Likely wrote:
> On Tue, 04 Feb 2014 13:09:32 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > Enable reserved memory initialization from device tree.
> >
> > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Cc: Laura Abbott <lauraa@codeaurora.org>
> > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > ---
> >  arch/arm/mm/init.c |    3 +++
> >  1 file changed, 3 insertions(+)
> >
> > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> > index 804d61566a53..ebafdb479410 100644
> > --- a/arch/arm/mm/init.c
> > +++ b/arch/arm/mm/init.c
> > @@ -17,6 +17,7 @@
> >  #include <linux/nodemask.h>
> >  #include <linux/initrd.h>
> >  #include <linux/of_fdt.h>
> > +#include <linux/of_reserved_mem.h>
> >  #include <linux/highmem.h>
> >  #include <linux/gfp.h>
> >  #include <linux/memblock.h>
> > @@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
> >  	if (mdesc->reserve)
> >  		mdesc->reserve();
> >
> > +	early_init_dt_scan_reserved_mem();
> > +
>
> The new binding is being made fundamental. If the reserved-memory node
> is present, then it needs to be honored, even if the kernel doesn't know
> how to use the regions. Therefore, This needs to be unconditional for
> all architectures. The hook should be called in early_init_dt_scan()
> (drivers/of/fdt.c) immediately after the early_init_dt_scan_memory()
> hook.

In theory this will be the best solution, but it practice there is a
problem. early_init_dt_scan() is called as the first function from kernel
booting code. That time there is no memory yet added to the system, so it
would be really hard to reserve anything. Memory nodes are being added
later either with memblock_add() or by some other arch specific way.

Finally, once all memory has been added to the system we can parse and
reserve all regions defined in the device tree. This really requires
creating another function which will be called by arch specific code.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* Re: [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
  2014-02-04 12:09   ` Marek Szyprowski
@ 2014-02-06 22:08     ` Laura Abbott
  -1 siblings, 0 replies; 60+ messages in thread
From: Laura Abbott @ 2014-02-06 22:08 UTC (permalink / raw)
  To: Marek Szyprowski, linux-kernel, linux-arm-kernel, linaro-mm-sig,
	devicetree, linux-doc
  Cc: Mark Rutland, Pawel Moll, Arnd Bergmann, Stephen Warren,
	Josh Cartwright, Benjamin Herrenschmidt, Tomasz Figa,
	Olof Johansson, Tomasz Figa, Michal Nazarewicz, Rob Herring,
	Kyungmin Park, Kumar Gala, Grant Likely, Ian Campbell,
	Nishanth Peethambaran, Sascha Hauer, Marc

Hi,

On 2/4/2014 4:09 AM, Marek Szyprowski wrote:
...
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index efd05102c405..ed9660adad77 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
>   obj-$(CONFIG_OF_PCI)	+= of_pci.o
>   obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
>   obj-$(CONFIG_OF_MTD)	+= of_mtd.o
> +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> new file mode 100644
> index 000000000000..f17cd56e68d9
> --- /dev/null
> +++ b/drivers/of/of_reserved_mem.c
> @@ -0,0 +1,219 @@
> +/*
> + * Device tree based initialization code for reserved memory.
> + *
> + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com
> + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
> + * Author: Josh Cartwright <joshc@codeaurora.org>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of the
> + * License or (at your optional) any later version of the license.
> + */
> +#include <linux/memblock.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/of_fdt.h>
> +#include <linux/of_platform.h>
> +#include <linux/mm.h>
> +#include <linux/sizes.h>
> +#include <linux/of_reserved_mem.h>
> +
> +#define MAX_RESERVED_REGIONS	16

Make this a config option?

> +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
> +static int reserved_mem_count;
> +
> +int __init of_parse_flat_dt_reg(unsigned long node, const char *uname,
> +				   phys_addr_t *base, phys_addr_t *size)
> +{
> +	unsigned long len;
> +	__be32 *prop;
> +
> +	prop = of_get_flat_dt_prop(node, "reg", &len);
> +	if (!prop)
> +		return -EINVAL;
> +
> +	if (len < (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) {
> +		pr_err("Reserved memory: invalid reg property in '%s' node.\n",
> +				uname);
> +		return -EINVAL;
> +	}
> +
> +	*base = dt_mem_next_cell(dt_root_addr_cells, &prop);
> +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
> +	return 0;
> +}
> +
> +int __init of_parse_flat_dt_size(unsigned long node, const char *uname,
> +				    phys_addr_t *size)
> +{
> +	unsigned long len;
> +	__be32 *prop;
> +
> +	prop = of_get_flat_dt_prop(node, "size", &len);
> +	if (!prop)
> +		return -EINVAL;
> +
> +	if (len < dt_root_size_cells * sizeof(__be32)) {
> +		pr_err("Reserved memory: invalid size property in '%s' node.\n",
> +				uname);
> +		return -EINVAL;
> +	}
> +
> +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
> +	return 0;
> +}
> +
> +static int __init rmem_default_early_setup(struct reserved_mem *rmem,
> +					   unsigned long node,
> +					   const char *uname)
> +{
> +	int err;
> +
> +	if (of_get_flat_dt_prop(node, "compatible", NULL))
> +		return -EINVAL;
> +
> +	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
> +	if (err)
> +		return err;
> +
> +	if (of_get_flat_dt_prop(node, "no-map", NULL))
> +		err = memblock_remove(rmem->base, rmem->size);
> +	else
> +		err = memblock_reserve(rmem->base, rmem->size);
> +

The CMA code aligns to pageblock size, do we need to do something 
similar here as well? With reserved it might not be much of an issue but 
we've hit issues before with non-pageblock aligned memblock_removed 
memory because the page structures are not initialized.

> +	if (err == 0)
> +		pr_info("Reserved memory: found '%s', memory base %pa, size %ld MiB\n",
> +			uname, &rmem->base, (unsigned long)rmem->size / SZ_1M);
> +
> +	return err;
> +}
> +
> +static const struct of_device_id rmem_default_id
> +	__used __section(__reservedmem_of_table_end) = {
> +	.data		= rmem_default_early_setup,
> +};
> +
> +static int __init fdt_scan_reserved_mem(unsigned long node, const char *uname,
> +					int depth, void *data)
> +{
> +	struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
> +	extern const struct of_device_id __reservedmem_of_table[];
> +	const struct of_device_id *id;
> +	const char *status;
> +
> +	if (reserved_mem_count == ARRAY_SIZE(reserved_mem)) {
> +		pr_err("Reserved memory: not enough space all defined regions.\n");
> +		return -ENOSPC;
> +	}
> +
> +	status = of_get_flat_dt_prop(node, "status", NULL);
> +	if (status && strcmp(status, "okay") != 0)
> +		return 0;
> +

strncmp(status, "ok", 2) to handle alternate spellings

>

Thanks,
Laura

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-06 22:08     ` Laura Abbott
  0 siblings, 0 replies; 60+ messages in thread
From: Laura Abbott @ 2014-02-06 22:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 2/4/2014 4:09 AM, Marek Szyprowski wrote:
...
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index efd05102c405..ed9660adad77 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
>   obj-$(CONFIG_OF_PCI)	+= of_pci.o
>   obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
>   obj-$(CONFIG_OF_MTD)	+= of_mtd.o
> +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> new file mode 100644
> index 000000000000..f17cd56e68d9
> --- /dev/null
> +++ b/drivers/of/of_reserved_mem.c
> @@ -0,0 +1,219 @@
> +/*
> + * Device tree based initialization code for reserved memory.
> + *
> + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com
> + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
> + * Author: Josh Cartwright <joshc@codeaurora.org>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of the
> + * License or (at your optional) any later version of the license.
> + */
> +#include <linux/memblock.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/of_fdt.h>
> +#include <linux/of_platform.h>
> +#include <linux/mm.h>
> +#include <linux/sizes.h>
> +#include <linux/of_reserved_mem.h>
> +
> +#define MAX_RESERVED_REGIONS	16

Make this a config option?

> +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
> +static int reserved_mem_count;
> +
> +int __init of_parse_flat_dt_reg(unsigned long node, const char *uname,
> +				   phys_addr_t *base, phys_addr_t *size)
> +{
> +	unsigned long len;
> +	__be32 *prop;
> +
> +	prop = of_get_flat_dt_prop(node, "reg", &len);
> +	if (!prop)
> +		return -EINVAL;
> +
> +	if (len < (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) {
> +		pr_err("Reserved memory: invalid reg property in '%s' node.\n",
> +				uname);
> +		return -EINVAL;
> +	}
> +
> +	*base = dt_mem_next_cell(dt_root_addr_cells, &prop);
> +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
> +	return 0;
> +}
> +
> +int __init of_parse_flat_dt_size(unsigned long node, const char *uname,
> +				    phys_addr_t *size)
> +{
> +	unsigned long len;
> +	__be32 *prop;
> +
> +	prop = of_get_flat_dt_prop(node, "size", &len);
> +	if (!prop)
> +		return -EINVAL;
> +
> +	if (len < dt_root_size_cells * sizeof(__be32)) {
> +		pr_err("Reserved memory: invalid size property in '%s' node.\n",
> +				uname);
> +		return -EINVAL;
> +	}
> +
> +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
> +	return 0;
> +}
> +
> +static int __init rmem_default_early_setup(struct reserved_mem *rmem,
> +					   unsigned long node,
> +					   const char *uname)
> +{
> +	int err;
> +
> +	if (of_get_flat_dt_prop(node, "compatible", NULL))
> +		return -EINVAL;
> +
> +	err = of_parse_flat_dt_reg(node, uname, &rmem->base, &rmem->size);
> +	if (err)
> +		return err;
> +
> +	if (of_get_flat_dt_prop(node, "no-map", NULL))
> +		err = memblock_remove(rmem->base, rmem->size);
> +	else
> +		err = memblock_reserve(rmem->base, rmem->size);
> +

The CMA code aligns to pageblock size, do we need to do something 
similar here as well? With reserved it might not be much of an issue but 
we've hit issues before with non-pageblock aligned memblock_removed 
memory because the page structures are not initialized.

> +	if (err == 0)
> +		pr_info("Reserved memory: found '%s', memory base %pa, size %ld MiB\n",
> +			uname, &rmem->base, (unsigned long)rmem->size / SZ_1M);
> +
> +	return err;
> +}
> +
> +static const struct of_device_id rmem_default_id
> +	__used __section(__reservedmem_of_table_end) = {
> +	.data		= rmem_default_early_setup,
> +};
> +
> +static int __init fdt_scan_reserved_mem(unsigned long node, const char *uname,
> +					int depth, void *data)
> +{
> +	struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
> +	extern const struct of_device_id __reservedmem_of_table[];
> +	const struct of_device_id *id;
> +	const char *status;
> +
> +	if (reserved_mem_count == ARRAY_SIZE(reserved_mem)) {
> +		pr_err("Reserved memory: not enough space all defined regions.\n");
> +		return -ENOSPC;
> +	}
> +
> +	status = of_get_flat_dt_prop(node, "status", NULL);
> +	if (status && strcmp(status, "okay") != 0)
> +		return 0;
> +

strncmp(status, "ok", 2) to handle alternate spellings

>

Thanks,
Laura

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* Re: [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
  2014-02-06 13:26       ` Marek Szyprowski
@ 2014-02-10 21:59         ` Grant Likely
  -1 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-10 21:59 UTC (permalink / raw)
  To: Marek Szyprowski, linux-kernel, linux-arm-kernel, linaro-mm-sig,
	devicetree, linux-doc
  Cc: Kyungmin Park, Benjamin Herrenschmidt, Arnd Bergmann,
	Michal Nazarewicz, Tomasz Figa, Sascha Hauer, Laura Abbott,
	Rob Herring, Olof Johansson, Pawel Moll, Mark Rutland,
	Stephen Warren, Ian Campbell, Tomasz Figa, Kumar Gala,
	Nishanth Peethambaran, Marc, Josh Cartwright

On Thu, 06 Feb 2014 14:26:13 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> Hello,
> 
> On 2014-02-05 11:15, Grant Likely wrote:
> > On Tue, 04 Feb 2014 13:09:32 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > > Enable reserved memory initialization from device tree.
> > >
> > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > Cc: Laura Abbott <lauraa@codeaurora.org>
> > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > ---
> > >  arch/arm/mm/init.c |    3 +++
> > >  1 file changed, 3 insertions(+)
> > >
> > > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> > > index 804d61566a53..ebafdb479410 100644
> > > --- a/arch/arm/mm/init.c
> > > +++ b/arch/arm/mm/init.c
> > > @@ -17,6 +17,7 @@
> > >  #include <linux/nodemask.h>
> > >  #include <linux/initrd.h>
> > >  #include <linux/of_fdt.h>
> > > +#include <linux/of_reserved_mem.h>
> > >  #include <linux/highmem.h>
> > >  #include <linux/gfp.h>
> > >  #include <linux/memblock.h>
> > > @@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
> > >  	if (mdesc->reserve)
> > >  		mdesc->reserve();
> > >
> > > +	early_init_dt_scan_reserved_mem();
> > > +
> >
> > The new binding is being made fundamental. If the reserved-memory node
> > is present, then it needs to be honored, even if the kernel doesn't know
> > how to use the regions. Therefore, This needs to be unconditional for
> > all architectures. The hook should be called in early_init_dt_scan()
> > (drivers/of/fdt.c) immediately after the early_init_dt_scan_memory()
> > hook.
> 
> In theory this will be the best solution, but it practice there is a
> problem. early_init_dt_scan() is called as the first function from kernel
> booting code. That time there is no memory yet added to the system, so it
> would be really hard to reserve anything. Memory nodes are being added
> later either with memblock_add() or by some other arch specific way.

Hmmm, depends on the architecture. On ARM the memory is loaded into the
meminfo structure first, and it isn't until arm_memblock_init() that
memblock_add() gets called on all the regions. Some architectures do the
memblock_add() directly from early_init_dt_add_memory_arch() function.

The default early_init_dt_add_memory_arch() in drivers/of/fdt.c is
overridden by ARM and a number of other architectures. However...

> Finally, once all memory has been added to the system we can parse and
> reserve all regions defined in the device tree. This really requires
> creating another function which will be called by arch specific code.

...Or it means getting rid of meminfo entirely so that memblock is
available earlier. Laura Abbott has just posted v2 of her series to do
exactly that. If you base on that then you should be able to do exactly
what I suggested.

g.

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

* [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
@ 2014-02-10 21:59         ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-10 21:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 06 Feb 2014 14:26:13 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> Hello,
> 
> On 2014-02-05 11:15, Grant Likely wrote:
> > On Tue, 04 Feb 2014 13:09:32 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > > Enable reserved memory initialization from device tree.
> > >
> > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > Cc: Laura Abbott <lauraa@codeaurora.org>
> > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > ---
> > >  arch/arm/mm/init.c |    3 +++
> > >  1 file changed, 3 insertions(+)
> > >
> > > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> > > index 804d61566a53..ebafdb479410 100644
> > > --- a/arch/arm/mm/init.c
> > > +++ b/arch/arm/mm/init.c
> > > @@ -17,6 +17,7 @@
> > >  #include <linux/nodemask.h>
> > >  #include <linux/initrd.h>
> > >  #include <linux/of_fdt.h>
> > > +#include <linux/of_reserved_mem.h>
> > >  #include <linux/highmem.h>
> > >  #include <linux/gfp.h>
> > >  #include <linux/memblock.h>
> > > @@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
> > >  	if (mdesc->reserve)
> > >  		mdesc->reserve();
> > >
> > > +	early_init_dt_scan_reserved_mem();
> > > +
> >
> > The new binding is being made fundamental. If the reserved-memory node
> > is present, then it needs to be honored, even if the kernel doesn't know
> > how to use the regions. Therefore, This needs to be unconditional for
> > all architectures. The hook should be called in early_init_dt_scan()
> > (drivers/of/fdt.c) immediately after the early_init_dt_scan_memory()
> > hook.
> 
> In theory this will be the best solution, but it practice there is a
> problem. early_init_dt_scan() is called as the first function from kernel
> booting code. That time there is no memory yet added to the system, so it
> would be really hard to reserve anything. Memory nodes are being added
> later either with memblock_add() or by some other arch specific way.

Hmmm, depends on the architecture. On ARM the memory is loaded into the
meminfo structure first, and it isn't until arm_memblock_init() that
memblock_add() gets called on all the regions. Some architectures do the
memblock_add() directly from early_init_dt_add_memory_arch() function.

The default early_init_dt_add_memory_arch() in drivers/of/fdt.c is
overridden by ARM and a number of other architectures. However...

> Finally, once all memory has been added to the system we can parse and
> reserve all regions defined in the device tree. This really requires
> creating another function which will be called by arch specific code.

...Or it means getting rid of meminfo entirely so that memblock is
available earlier. Laura Abbott has just posted v2 of her series to do
exactly that. If you base on that then you should be able to do exactly
what I suggested.

g.

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

* Re: [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
  2014-02-10 21:59         ` Grant Likely
@ 2014-02-11 10:52           ` Marek Szyprowski
  -1 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-11 10:52 UTC (permalink / raw)
  To: Grant Likely, linux-kernel, linux-arm-kernel, linaro-mm-sig,
	devicetree, linux-doc
  Cc: Kyungmin Park, Benjamin Herrenschmidt, Arnd Bergmann,
	Michal Nazarewicz, Tomasz Figa, Sascha Hauer, Laura Abbott,
	Rob Herring, Olof Johansson, Pawel Moll, Mark Rutland,
	Stephen Warren, Ian Campbell, Tomasz Figa, Kumar Gala,
	Nishanth Peethambaran, Marc, Josh Cartwright


On 2014-02-10 22:59, Grant Likely wrote:
> On Thu, 06 Feb 2014 14:26:13 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > Hello,
> >
> > On 2014-02-05 11:15, Grant Likely wrote:
> > > On Tue, 04 Feb 2014 13:09:32 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > > > Enable reserved memory initialization from device tree.
> > > >
> > > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > > Cc: Laura Abbott <lauraa@codeaurora.org>
> > > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > > ---
> > > >  arch/arm/mm/init.c |    3 +++
> > > >  1 file changed, 3 insertions(+)
> > > >
> > > > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> > > > index 804d61566a53..ebafdb479410 100644
> > > > --- a/arch/arm/mm/init.c
> > > > +++ b/arch/arm/mm/init.c
> > > > @@ -17,6 +17,7 @@
> > > >  #include <linux/nodemask.h>
> > > >  #include <linux/initrd.h>
> > > >  #include <linux/of_fdt.h>
> > > > +#include <linux/of_reserved_mem.h>
> > > >  #include <linux/highmem.h>
> > > >  #include <linux/gfp.h>
> > > >  #include <linux/memblock.h>
> > > > @@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
> > > >  	if (mdesc->reserve)
> > > >  		mdesc->reserve();
> > > >
> > > > +	early_init_dt_scan_reserved_mem();
> > > > +
> > >
> > > The new binding is being made fundamental. If the reserved-memory node
> > > is present, then it needs to be honored, even if the kernel doesn't know
> > > how to use the regions. Therefore, This needs to be unconditional for
> > > all architectures. The hook should be called in early_init_dt_scan()
> > > (drivers/of/fdt.c) immediately after the early_init_dt_scan_memory()
> > > hook.
> >
> > In theory this will be the best solution, but it practice there is a
> > problem. early_init_dt_scan() is called as the first function from kernel
> > booting code. That time there is no memory yet added to the system, so it
> > would be really hard to reserve anything. Memory nodes are being added
> > later either with memblock_add() or by some other arch specific way.
>
> Hmmm, depends on the architecture. On ARM the memory is loaded into the
> meminfo structure first, and it isn't until arm_memblock_init() that
> memblock_add() gets called on all the regions. Some architectures do the
> memblock_add() directly from early_init_dt_add_memory_arch() function.
>
> The default early_init_dt_add_memory_arch() in drivers/of/fdt.c is
> overridden by ARM and a number of other architectures. However...
>
> > Finally, once all memory has been added to the system we can parse and
> > reserve all regions defined in the device tree. This really requires
> > creating another function which will be called by arch specific code.
>
> ...Or it means getting rid of meminfo entirely so that memblock is
> available earlier. Laura Abbott has just posted v2 of her series to do
> exactly that. If you base on that then you should be able to do exactly
> what I suggested.

I've checked Laura's patches and in fact it is possible to do memory
reservation as a last step in early_init_dt_scan_memory(). However still
see some problem which I have no idea how to resolve. Right now I focus
only on ARM, so I have no idea how it is solved by other architectures.
On of the key features of the new binding is the ability to automatically
allocate reserved regions of the given size. However kernel, initrd, dt
and other sub-arch specific critical regions are marked/allocated in
arm_memblock_init(), which is called after setup_machine_fdt(). This
might lead to some serious failures when automatically reserved region
overlaps with some critical resources. Do you have any idea how to solve
this without a new callback?

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


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

* [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
@ 2014-02-11 10:52           ` Marek Szyprowski
  0 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-11 10:52 UTC (permalink / raw)
  To: linux-arm-kernel


On 2014-02-10 22:59, Grant Likely wrote:
> On Thu, 06 Feb 2014 14:26:13 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > Hello,
> >
> > On 2014-02-05 11:15, Grant Likely wrote:
> > > On Tue, 04 Feb 2014 13:09:32 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > > > Enable reserved memory initialization from device tree.
> > > >
> > > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > > Cc: Laura Abbott <lauraa@codeaurora.org>
> > > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > > ---
> > > >  arch/arm/mm/init.c |    3 +++
> > > >  1 file changed, 3 insertions(+)
> > > >
> > > > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> > > > index 804d61566a53..ebafdb479410 100644
> > > > --- a/arch/arm/mm/init.c
> > > > +++ b/arch/arm/mm/init.c
> > > > @@ -17,6 +17,7 @@
> > > >  #include <linux/nodemask.h>
> > > >  #include <linux/initrd.h>
> > > >  #include <linux/of_fdt.h>
> > > > +#include <linux/of_reserved_mem.h>
> > > >  #include <linux/highmem.h>
> > > >  #include <linux/gfp.h>
> > > >  #include <linux/memblock.h>
> > > > @@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
> > > >  	if (mdesc->reserve)
> > > >  		mdesc->reserve();
> > > >
> > > > +	early_init_dt_scan_reserved_mem();
> > > > +
> > >
> > > The new binding is being made fundamental. If the reserved-memory node
> > > is present, then it needs to be honored, even if the kernel doesn't know
> > > how to use the regions. Therefore, This needs to be unconditional for
> > > all architectures. The hook should be called in early_init_dt_scan()
> > > (drivers/of/fdt.c) immediately after the early_init_dt_scan_memory()
> > > hook.
> >
> > In theory this will be the best solution, but it practice there is a
> > problem. early_init_dt_scan() is called as the first function from kernel
> > booting code. That time there is no memory yet added to the system, so it
> > would be really hard to reserve anything. Memory nodes are being added
> > later either with memblock_add() or by some other arch specific way.
>
> Hmmm, depends on the architecture. On ARM the memory is loaded into the
> meminfo structure first, and it isn't until arm_memblock_init() that
> memblock_add() gets called on all the regions. Some architectures do the
> memblock_add() directly from early_init_dt_add_memory_arch() function.
>
> The default early_init_dt_add_memory_arch() in drivers/of/fdt.c is
> overridden by ARM and a number of other architectures. However...
>
> > Finally, once all memory has been added to the system we can parse and
> > reserve all regions defined in the device tree. This really requires
> > creating another function which will be called by arch specific code.
>
> ...Or it means getting rid of meminfo entirely so that memblock is
> available earlier. Laura Abbott has just posted v2 of her series to do
> exactly that. If you base on that then you should be able to do exactly
> what I suggested.

I've checked Laura's patches and in fact it is possible to do memory
reservation as a last step in early_init_dt_scan_memory(). However still
see some problem which I have no idea how to resolve. Right now I focus
only on ARM, so I have no idea how it is solved by other architectures.
On of the key features of the new binding is the ability to automatically
allocate reserved regions of the given size. However kernel, initrd, dt
and other sub-arch specific critical regions are marked/allocated in
arm_memblock_init(), which is called after setup_machine_fdt(). This
might lead to some serious failures when automatically reserved region
overlaps with some critical resources. Do you have any idea how to solve
this without a new callback?

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* Re: [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
  2014-02-05 11:05     ` Grant Likely
@ 2014-02-11 11:45       ` Marek Szyprowski
  -1 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-11 11:45 UTC (permalink / raw)
  To: Grant Likely, linux-kernel, linux-arm-kernel, linaro-mm-sig,
	devicetree, linux-doc
  Cc: Kyungmin Park, Benjamin Herrenschmidt, Arnd Bergmann,
	Michal Nazarewicz, Tomasz Figa, Sascha Hauer, Laura Abbott,
	Rob Herring, Olof Johansson, Pawel Moll, Mark Rutland,
	Stephen Warren, Ian Campbell, Tomasz Figa, Kumar Gala,
	Nishanth Peethambaran, Marc, Josh Cartwright

Hello,

On 2014-02-05 12:05, Grant Likely wrote:
> On Tue, 04 Feb 2014 13:09:29 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > This patch adds device tree support for contiguous and reserved memory
> > regions defined in device tree.
> >
> > Large memory blocks can be reliably reserved only during early boot.
> > This must happen before the whole memory management subsystem is
> > initialized, because we need to ensure that the given contiguous blocks
> > are not yet allocated by kernel. Also it must happen before kernel
> > mappings for the whole low memory are created, to ensure that there will
> > be no mappings (for reserved blocks) or mapping with special properties
> > can be created (for CMA blocks). This all happens before device tree
> > structures are unflattened, so we need to get reserved memory layout
> > directly from fdt.
> >
> > Later, those reserved memory regions are assigned to devices on each
> > device structure initialization.
> >
> > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Cc: Laura Abbott <lauraa@codeaurora.org>
> > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > [joshc: rework to implement new DT binding, provide mechanism for
> >  plugging in new reserved-memory node handlers via
> >  RESERVEDMEM_OF_DECLARE]
> > Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
> > [mszyprow: little code cleanup]
> > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > ---
> >  drivers/of/Kconfig                |    6 +
> >  drivers/of/Makefile               |    1 +
> >  drivers/of/of_reserved_mem.c      |  219 +++++++++++++++++++++++++++++++++++++
> >  drivers/of/platform.c             |    7 ++
> >  include/asm-generic/vmlinux.lds.h |   11 ++
> >  include/linux/of_reserved_mem.h   |   62 +++++++++++
> >  6 files changed, 306 insertions(+)
> >  create mode 100644 drivers/of/of_reserved_mem.c
> >  create mode 100644 include/linux/of_reserved_mem.h
> >
> > diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> > index c6973f101a3e..aba13df56f3a 100644
> > --- a/drivers/of/Kconfig
> > +++ b/drivers/of/Kconfig
> > @@ -75,4 +75,10 @@ config OF_MTD
> >  	depends on MTD
> >  	def_bool y
> >
> > +config OF_RESERVED_MEM
> > +	depends on HAVE_MEMBLOCK
> > +	def_bool y
> > +	help
> > +	  Helpers to allow for reservation of memory regions
> > +
> >  endmenu # OF
> > diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> > index efd05102c405..ed9660adad77 100644
> > --- a/drivers/of/Makefile
> > +++ b/drivers/of/Makefile
> > @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
> >  obj-$(CONFIG_OF_PCI)	+= of_pci.o
> >  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
> >  obj-$(CONFIG_OF_MTD)	+= of_mtd.o
> > +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> > diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> > new file mode 100644
> > index 000000000000..f17cd56e68d9
> > --- /dev/null
> > +++ b/drivers/of/of_reserved_mem.c
> > @@ -0,0 +1,219 @@
> > +/*
> > + * Device tree based initialization code for reserved memory.
> > + *
> > + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
> > + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> > + *		http://www.samsung.com
> > + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
> > + * Author: Josh Cartwright <joshc@codeaurora.org>
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation; either version 2 of the
> > + * License or (at your optional) any later version of the license.
> > + */
> > +#include <linux/memblock.h>
> > +#include <linux/err.h>
> > +#include <linux/of.h>
> > +#include <linux/of_fdt.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/mm.h>
> > +#include <linux/sizes.h>
> > +#include <linux/of_reserved_mem.h>
> > +
> > +#define MAX_RESERVED_REGIONS	16
> > +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
> > +static int reserved_mem_count;
> > +
> > +int __init of_parse_flat_dt_reg(unsigned long node, const char *uname,
> > +				   phys_addr_t *base, phys_addr_t *size)
>
> Useful utility function; move to drivers/of/fdt.c
>
> > +{
> > +	unsigned long len;
> > +	__be32 *prop;
> > +
> > +	prop = of_get_flat_dt_prop(node, "reg", &len);
> > +	if (!prop)
> > +		return -EINVAL;
> > +
> > +	if (len < (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) {
> > +		pr_err("Reserved memory: invalid reg property in '%s' node.\n",
> > +				uname);
> > +		return -EINVAL;
> > +	}
>
> This is /okay/ for an initial implementation, but it is naive. While I
> suggested making #address-cells and #size-cells equal the root node
> values for the purpose of simplicity, it should still be perfectly valid
> to have different values if the ranges property is correctly formed.
>
> > +
> > +	*base = dt_mem_next_cell(dt_root_addr_cells, &prop);
> > +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
>
> Future enhancement; allow for parsing more than just the first reg
> tuple.

One more question. Does it really makes any sense to support more than 
one tuple
for reg property? For consistency we should also allow more than one 
entry in
size, align and alloc-ranges property, but I don't see any benefits for 
defining
more than one range for a single region. Same can be achieved by 
defining more
regions instead if one really needs such configuration.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


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

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-11 11:45       ` Marek Szyprowski
  0 siblings, 0 replies; 60+ messages in thread
From: Marek Szyprowski @ 2014-02-11 11:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On 2014-02-05 12:05, Grant Likely wrote:
> On Tue, 04 Feb 2014 13:09:29 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > This patch adds device tree support for contiguous and reserved memory
> > regions defined in device tree.
> >
> > Large memory blocks can be reliably reserved only during early boot.
> > This must happen before the whole memory management subsystem is
> > initialized, because we need to ensure that the given contiguous blocks
> > are not yet allocated by kernel. Also it must happen before kernel
> > mappings for the whole low memory are created, to ensure that there will
> > be no mappings (for reserved blocks) or mapping with special properties
> > can be created (for CMA blocks). This all happens before device tree
> > structures are unflattened, so we need to get reserved memory layout
> > directly from fdt.
> >
> > Later, those reserved memory regions are assigned to devices on each
> > device structure initialization.
> >
> > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Cc: Laura Abbott <lauraa@codeaurora.org>
> > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > [joshc: rework to implement new DT binding, provide mechanism for
> >  plugging in new reserved-memory node handlers via
> >  RESERVEDMEM_OF_DECLARE]
> > Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
> > [mszyprow: little code cleanup]
> > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > ---
> >  drivers/of/Kconfig                |    6 +
> >  drivers/of/Makefile               |    1 +
> >  drivers/of/of_reserved_mem.c      |  219 +++++++++++++++++++++++++++++++++++++
> >  drivers/of/platform.c             |    7 ++
> >  include/asm-generic/vmlinux.lds.h |   11 ++
> >  include/linux/of_reserved_mem.h   |   62 +++++++++++
> >  6 files changed, 306 insertions(+)
> >  create mode 100644 drivers/of/of_reserved_mem.c
> >  create mode 100644 include/linux/of_reserved_mem.h
> >
> > diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> > index c6973f101a3e..aba13df56f3a 100644
> > --- a/drivers/of/Kconfig
> > +++ b/drivers/of/Kconfig
> > @@ -75,4 +75,10 @@ config OF_MTD
> >  	depends on MTD
> >  	def_bool y
> >
> > +config OF_RESERVED_MEM
> > +	depends on HAVE_MEMBLOCK
> > +	def_bool y
> > +	help
> > +	  Helpers to allow for reservation of memory regions
> > +
> >  endmenu # OF
> > diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> > index efd05102c405..ed9660adad77 100644
> > --- a/drivers/of/Makefile
> > +++ b/drivers/of/Makefile
> > @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
> >  obj-$(CONFIG_OF_PCI)	+= of_pci.o
> >  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
> >  obj-$(CONFIG_OF_MTD)	+= of_mtd.o
> > +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> > diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> > new file mode 100644
> > index 000000000000..f17cd56e68d9
> > --- /dev/null
> > +++ b/drivers/of/of_reserved_mem.c
> > @@ -0,0 +1,219 @@
> > +/*
> > + * Device tree based initialization code for reserved memory.
> > + *
> > + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
> > + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> > + *		http://www.samsung.com
> > + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
> > + * Author: Josh Cartwright <joshc@codeaurora.org>
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation; either version 2 of the
> > + * License or (at your optional) any later version of the license.
> > + */
> > +#include <linux/memblock.h>
> > +#include <linux/err.h>
> > +#include <linux/of.h>
> > +#include <linux/of_fdt.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/mm.h>
> > +#include <linux/sizes.h>
> > +#include <linux/of_reserved_mem.h>
> > +
> > +#define MAX_RESERVED_REGIONS	16
> > +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
> > +static int reserved_mem_count;
> > +
> > +int __init of_parse_flat_dt_reg(unsigned long node, const char *uname,
> > +				   phys_addr_t *base, phys_addr_t *size)
>
> Useful utility function; move to drivers/of/fdt.c
>
> > +{
> > +	unsigned long len;
> > +	__be32 *prop;
> > +
> > +	prop = of_get_flat_dt_prop(node, "reg", &len);
> > +	if (!prop)
> > +		return -EINVAL;
> > +
> > +	if (len < (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) {
> > +		pr_err("Reserved memory: invalid reg property in '%s' node.\n",
> > +				uname);
> > +		return -EINVAL;
> > +	}
>
> This is /okay/ for an initial implementation, but it is naive. While I
> suggested making #address-cells and #size-cells equal the root node
> values for the purpose of simplicity, it should still be perfectly valid
> to have different values if the ranges property is correctly formed.
>
> > +
> > +	*base = dt_mem_next_cell(dt_root_addr_cells, &prop);
> > +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
>
> Future enhancement; allow for parsing more than just the first reg
> tuple.

One more question. Does it really makes any sense to support more than 
one tuple
for reg property? For consistency we should also allow more than one 
entry in
size, align and alloc-ranges property, but I don't see any benefits for 
defining
more than one range for a single region. Same can be achieved by 
defining more
regions instead if one really needs such configuration.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* Re: [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
  2014-02-11 10:52           ` Marek Szyprowski
@ 2014-02-11 11:50             ` Grant Likely
  -1 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-11 11:50 UTC (permalink / raw)
  To: Marek Szyprowski, linux-kernel, linux-arm-kernel, linaro-mm-sig,
	devicetree, linux-doc
  Cc: Kyungmin Park, Benjamin Herrenschmidt, Arnd Bergmann,
	Michal Nazarewicz, Tomasz Figa, Sascha Hauer, Laura Abbott,
	Rob Herring, Olof Johansson, Pawel Moll, Mark Rutland,
	Stephen Warren, Ian Campbell, Tomasz Figa, Kumar Gala,
	Nishanth Peethambaran, Marc, Josh Cartwright

On Tue, 11 Feb 2014 11:52:42 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> 
> On 2014-02-10 22:59, Grant Likely wrote:
> > On Thu, 06 Feb 2014 14:26:13 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > > Hello,
> > >
> > > On 2014-02-05 11:15, Grant Likely wrote:
> > > > On Tue, 04 Feb 2014 13:09:32 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > > > > Enable reserved memory initialization from device tree.
> > > > >
> > > > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > > > Cc: Laura Abbott <lauraa@codeaurora.org>
> > > > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > > > ---
> > > > >  arch/arm/mm/init.c |    3 +++
> > > > >  1 file changed, 3 insertions(+)
> > > > >
> > > > > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> > > > > index 804d61566a53..ebafdb479410 100644
> > > > > --- a/arch/arm/mm/init.c
> > > > > +++ b/arch/arm/mm/init.c
> > > > > @@ -17,6 +17,7 @@
> > > > >  #include <linux/nodemask.h>
> > > > >  #include <linux/initrd.h>
> > > > >  #include <linux/of_fdt.h>
> > > > > +#include <linux/of_reserved_mem.h>
> > > > >  #include <linux/highmem.h>
> > > > >  #include <linux/gfp.h>
> > > > >  #include <linux/memblock.h>
> > > > > @@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
> > > > >  	if (mdesc->reserve)
> > > > >  		mdesc->reserve();
> > > > >
> > > > > +	early_init_dt_scan_reserved_mem();
> > > > > +
> > > >
> > > > The new binding is being made fundamental. If the reserved-memory node
> > > > is present, then it needs to be honored, even if the kernel doesn't know
> > > > how to use the regions. Therefore, This needs to be unconditional for
> > > > all architectures. The hook should be called in early_init_dt_scan()
> > > > (drivers/of/fdt.c) immediately after the early_init_dt_scan_memory()
> > > > hook.
> > >
> > > In theory this will be the best solution, but it practice there is a
> > > problem. early_init_dt_scan() is called as the first function from kernel
> > > booting code. That time there is no memory yet added to the system, so it
> > > would be really hard to reserve anything. Memory nodes are being added
> > > later either with memblock_add() or by some other arch specific way.
> >
> > Hmmm, depends on the architecture. On ARM the memory is loaded into the
> > meminfo structure first, and it isn't until arm_memblock_init() that
> > memblock_add() gets called on all the regions. Some architectures do the
> > memblock_add() directly from early_init_dt_add_memory_arch() function.
> >
> > The default early_init_dt_add_memory_arch() in drivers/of/fdt.c is
> > overridden by ARM and a number of other architectures. However...
> >
> > > Finally, once all memory has been added to the system we can parse and
> > > reserve all regions defined in the device tree. This really requires
> > > creating another function which will be called by arch specific code.
> >
> > ...Or it means getting rid of meminfo entirely so that memblock is
> > available earlier. Laura Abbott has just posted v2 of her series to do
> > exactly that. If you base on that then you should be able to do exactly
> > what I suggested.
> 
> I've checked Laura's patches and in fact it is possible to do memory
> reservation as a last step in early_init_dt_scan_memory(). However still
> see some problem which I have no idea how to resolve. Right now I focus
> only on ARM, so I have no idea how it is solved by other architectures.

It isn't at the moment because no other architectures are doing dynamic
allocation of regions in this way.

> On of the key features of the new binding is the ability to automatically
> allocate reserved regions of the given size. However kernel, initrd, dt
> and other sub-arch specific critical regions are marked/allocated in
> arm_memblock_init(), which is called after setup_machine_fdt(). This
> might lead to some serious failures when automatically reserved region
> overlaps with some critical resources. Do you have any idea how to solve
> this without a new callback?

Not without moving the kernel/initrd/fdt reservation earlier, which can
certainly be done after Laura's series is applied. It would also be
possible to split up the fixed regions from the dynamic regions so that
the dynamic stuff would be done later.

However, I don't want to block this series on Laura's rework. Go ahead
and keep it as a separate hook, but make the other changes I suggested,
particularly with regard to making the hook architecture independent.
Further rework can be done later after Laura's series is merged.

g.

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

* [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
@ 2014-02-11 11:50             ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-11 11:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 11 Feb 2014 11:52:42 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> 
> On 2014-02-10 22:59, Grant Likely wrote:
> > On Thu, 06 Feb 2014 14:26:13 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > > Hello,
> > >
> > > On 2014-02-05 11:15, Grant Likely wrote:
> > > > On Tue, 04 Feb 2014 13:09:32 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > > > > Enable reserved memory initialization from device tree.
> > > > >
> > > > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > > > Cc: Laura Abbott <lauraa@codeaurora.org>
> > > > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > > > ---
> > > > >  arch/arm/mm/init.c |    3 +++
> > > > >  1 file changed, 3 insertions(+)
> > > > >
> > > > > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> > > > > index 804d61566a53..ebafdb479410 100644
> > > > > --- a/arch/arm/mm/init.c
> > > > > +++ b/arch/arm/mm/init.c
> > > > > @@ -17,6 +17,7 @@
> > > > >  #include <linux/nodemask.h>
> > > > >  #include <linux/initrd.h>
> > > > >  #include <linux/of_fdt.h>
> > > > > +#include <linux/of_reserved_mem.h>
> > > > >  #include <linux/highmem.h>
> > > > >  #include <linux/gfp.h>
> > > > >  #include <linux/memblock.h>
> > > > > @@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
> > > > >  	if (mdesc->reserve)
> > > > >  		mdesc->reserve();
> > > > >
> > > > > +	early_init_dt_scan_reserved_mem();
> > > > > +
> > > >
> > > > The new binding is being made fundamental. If the reserved-memory node
> > > > is present, then it needs to be honored, even if the kernel doesn't know
> > > > how to use the regions. Therefore, This needs to be unconditional for
> > > > all architectures. The hook should be called in early_init_dt_scan()
> > > > (drivers/of/fdt.c) immediately after the early_init_dt_scan_memory()
> > > > hook.
> > >
> > > In theory this will be the best solution, but it practice there is a
> > > problem. early_init_dt_scan() is called as the first function from kernel
> > > booting code. That time there is no memory yet added to the system, so it
> > > would be really hard to reserve anything. Memory nodes are being added
> > > later either with memblock_add() or by some other arch specific way.
> >
> > Hmmm, depends on the architecture. On ARM the memory is loaded into the
> > meminfo structure first, and it isn't until arm_memblock_init() that
> > memblock_add() gets called on all the regions. Some architectures do the
> > memblock_add() directly from early_init_dt_add_memory_arch() function.
> >
> > The default early_init_dt_add_memory_arch() in drivers/of/fdt.c is
> > overridden by ARM and a number of other architectures. However...
> >
> > > Finally, once all memory has been added to the system we can parse and
> > > reserve all regions defined in the device tree. This really requires
> > > creating another function which will be called by arch specific code.
> >
> > ...Or it means getting rid of meminfo entirely so that memblock is
> > available earlier. Laura Abbott has just posted v2 of her series to do
> > exactly that. If you base on that then you should be able to do exactly
> > what I suggested.
> 
> I've checked Laura's patches and in fact it is possible to do memory
> reservation as a last step in early_init_dt_scan_memory(). However still
> see some problem which I have no idea how to resolve. Right now I focus
> only on ARM, so I have no idea how it is solved by other architectures.

It isn't at the moment because no other architectures are doing dynamic
allocation of regions in this way.

> On of the key features of the new binding is the ability to automatically
> allocate reserved regions of the given size. However kernel, initrd, dt
> and other sub-arch specific critical regions are marked/allocated in
> arm_memblock_init(), which is called after setup_machine_fdt(). This
> might lead to some serious failures when automatically reserved region
> overlaps with some critical resources. Do you have any idea how to solve
> this without a new callback?

Not without moving the kernel/initrd/fdt reservation earlier, which can
certainly be done after Laura's series is applied. It would also be
possible to split up the fixed regions from the dynamic regions so that
the dynamic stuff would be done later.

However, I don't want to block this series on Laura's rework. Go ahead
and keep it as a separate hook, but make the other changes I suggested,
particularly with regard to making the hook architecture independent.
Further rework can be done later after Laura's series is merged.

g.

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

* Re: [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
  2014-02-11 11:45       ` Marek Szyprowski
@ 2014-02-11 12:13         ` Grant Likely
  -1 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-11 12:13 UTC (permalink / raw)
  To: Marek Szyprowski, linux-kernel, linux-arm-kernel, linaro-mm-sig,
	devicetree, linux-doc
  Cc: Kyungmin Park, Benjamin Herrenschmidt, Arnd Bergmann,
	Michal Nazarewicz, Tomasz Figa, Sascha Hauer, Laura Abbott,
	Rob Herring, Olof Johansson, Pawel Moll, Mark Rutland,
	Stephen Warren, Ian Campbell, Tomasz Figa, Kumar Gala,
	Nishanth Peethambaran, Marc, Josh Cartwright

On Tue, 11 Feb 2014 12:45:50 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> Hello,
> 
> On 2014-02-05 12:05, Grant Likely wrote:
> > On Tue, 04 Feb 2014 13:09:29 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > > This patch adds device tree support for contiguous and reserved memory
> > > regions defined in device tree.
> > >
> > > Large memory blocks can be reliably reserved only during early boot.
> > > This must happen before the whole memory management subsystem is
> > > initialized, because we need to ensure that the given contiguous blocks
> > > are not yet allocated by kernel. Also it must happen before kernel
> > > mappings for the whole low memory are created, to ensure that there will
> > > be no mappings (for reserved blocks) or mapping with special properties
> > > can be created (for CMA blocks). This all happens before device tree
> > > structures are unflattened, so we need to get reserved memory layout
> > > directly from fdt.
> > >
> > > Later, those reserved memory regions are assigned to devices on each
> > > device structure initialization.
> > >
> > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > Cc: Laura Abbott <lauraa@codeaurora.org>
> > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > [joshc: rework to implement new DT binding, provide mechanism for
> > >  plugging in new reserved-memory node handlers via
> > >  RESERVEDMEM_OF_DECLARE]
> > > Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
> > > [mszyprow: little code cleanup]
> > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > ---
> > >  drivers/of/Kconfig                |    6 +
> > >  drivers/of/Makefile               |    1 +
> > >  drivers/of/of_reserved_mem.c      |  219 +++++++++++++++++++++++++++++++++++++
> > >  drivers/of/platform.c             |    7 ++
> > >  include/asm-generic/vmlinux.lds.h |   11 ++
> > >  include/linux/of_reserved_mem.h   |   62 +++++++++++
> > >  6 files changed, 306 insertions(+)
> > >  create mode 100644 drivers/of/of_reserved_mem.c
> > >  create mode 100644 include/linux/of_reserved_mem.h
> > >
> > > diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> > > index c6973f101a3e..aba13df56f3a 100644
> > > --- a/drivers/of/Kconfig
> > > +++ b/drivers/of/Kconfig
> > > @@ -75,4 +75,10 @@ config OF_MTD
> > >  	depends on MTD
> > >  	def_bool y
> > >
> > > +config OF_RESERVED_MEM
> > > +	depends on HAVE_MEMBLOCK
> > > +	def_bool y
> > > +	help
> > > +	  Helpers to allow for reservation of memory regions
> > > +
> > >  endmenu # OF
> > > diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> > > index efd05102c405..ed9660adad77 100644
> > > --- a/drivers/of/Makefile
> > > +++ b/drivers/of/Makefile
> > > @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
> > >  obj-$(CONFIG_OF_PCI)	+= of_pci.o
> > >  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
> > >  obj-$(CONFIG_OF_MTD)	+= of_mtd.o
> > > +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> > > diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> > > new file mode 100644
> > > index 000000000000..f17cd56e68d9
> > > --- /dev/null
> > > +++ b/drivers/of/of_reserved_mem.c
> > > @@ -0,0 +1,219 @@
> > > +/*
> > > + * Device tree based initialization code for reserved memory.
> > > + *
> > > + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
> > > + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> > > + *		http://www.samsung.com
> > > + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
> > > + * Author: Josh Cartwright <joshc@codeaurora.org>
> > > + *
> > > + * This program is free software; you can redistribute it and/or
> > > + * modify it under the terms of the GNU General Public License as
> > > + * published by the Free Software Foundation; either version 2 of the
> > > + * License or (at your optional) any later version of the license.
> > > + */
> > > +#include <linux/memblock.h>
> > > +#include <linux/err.h>
> > > +#include <linux/of.h>
> > > +#include <linux/of_fdt.h>
> > > +#include <linux/of_platform.h>
> > > +#include <linux/mm.h>
> > > +#include <linux/sizes.h>
> > > +#include <linux/of_reserved_mem.h>
> > > +
> > > +#define MAX_RESERVED_REGIONS	16
> > > +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
> > > +static int reserved_mem_count;
> > > +
> > > +int __init of_parse_flat_dt_reg(unsigned long node, const char *uname,
> > > +				   phys_addr_t *base, phys_addr_t *size)
> >
> > Useful utility function; move to drivers/of/fdt.c
> >
> > > +{
> > > +	unsigned long len;
> > > +	__be32 *prop;
> > > +
> > > +	prop = of_get_flat_dt_prop(node, "reg", &len);
> > > +	if (!prop)
> > > +		return -EINVAL;
> > > +
> > > +	if (len < (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) {
> > > +		pr_err("Reserved memory: invalid reg property in '%s' node.\n",
> > > +				uname);
> > > +		return -EINVAL;
> > > +	}
> >
> > This is /okay/ for an initial implementation, but it is naive. While I
> > suggested making #address-cells and #size-cells equal the root node
> > values for the purpose of simplicity, it should still be perfectly valid
> > to have different values if the ranges property is correctly formed.
> >
> > > +
> > > +	*base = dt_mem_next_cell(dt_root_addr_cells, &prop);
> > > +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
> >
> > Future enhancement; allow for parsing more than just the first reg
> > tuple.
> 
> One more question. Does it really makes any sense to support more than
> one tuple for reg property? For consistency we should also allow more
> than one entry in size, align and alloc-ranges property, but I don't
> see any benefits for defining more than one range for a single region.
> Same can be achieved by defining more regions instead if one really
> needs such configuration.

Yes, if only because it is an define usage of the reg property. If a
devtree has multiple tuples in reg, then all of those tuples should be
treated as reserved, even if the kernel doesn't know how to use them.

I would not do the same for size/align/alloc-ranges unless there is a
very specific use case that you can define. These ones are different
from the static regions because they aren't ever used to protect
something that already exists in the memory.

g.


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

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-11 12:13         ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-11 12:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 11 Feb 2014 12:45:50 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> Hello,
> 
> On 2014-02-05 12:05, Grant Likely wrote:
> > On Tue, 04 Feb 2014 13:09:29 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > > This patch adds device tree support for contiguous and reserved memory
> > > regions defined in device tree.
> > >
> > > Large memory blocks can be reliably reserved only during early boot.
> > > This must happen before the whole memory management subsystem is
> > > initialized, because we need to ensure that the given contiguous blocks
> > > are not yet allocated by kernel. Also it must happen before kernel
> > > mappings for the whole low memory are created, to ensure that there will
> > > be no mappings (for reserved blocks) or mapping with special properties
> > > can be created (for CMA blocks). This all happens before device tree
> > > structures are unflattened, so we need to get reserved memory layout
> > > directly from fdt.
> > >
> > > Later, those reserved memory regions are assigned to devices on each
> > > device structure initialization.
> > >
> > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > Cc: Laura Abbott <lauraa@codeaurora.org>
> > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > [joshc: rework to implement new DT binding, provide mechanism for
> > >  plugging in new reserved-memory node handlers via
> > >  RESERVEDMEM_OF_DECLARE]
> > > Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
> > > [mszyprow: little code cleanup]
> > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > ---
> > >  drivers/of/Kconfig                |    6 +
> > >  drivers/of/Makefile               |    1 +
> > >  drivers/of/of_reserved_mem.c      |  219 +++++++++++++++++++++++++++++++++++++
> > >  drivers/of/platform.c             |    7 ++
> > >  include/asm-generic/vmlinux.lds.h |   11 ++
> > >  include/linux/of_reserved_mem.h   |   62 +++++++++++
> > >  6 files changed, 306 insertions(+)
> > >  create mode 100644 drivers/of/of_reserved_mem.c
> > >  create mode 100644 include/linux/of_reserved_mem.h
> > >
> > > diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> > > index c6973f101a3e..aba13df56f3a 100644
> > > --- a/drivers/of/Kconfig
> > > +++ b/drivers/of/Kconfig
> > > @@ -75,4 +75,10 @@ config OF_MTD
> > >  	depends on MTD
> > >  	def_bool y
> > >
> > > +config OF_RESERVED_MEM
> > > +	depends on HAVE_MEMBLOCK
> > > +	def_bool y
> > > +	help
> > > +	  Helpers to allow for reservation of memory regions
> > > +
> > >  endmenu # OF
> > > diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> > > index efd05102c405..ed9660adad77 100644
> > > --- a/drivers/of/Makefile
> > > +++ b/drivers/of/Makefile
> > > @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
> > >  obj-$(CONFIG_OF_PCI)	+= of_pci.o
> > >  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
> > >  obj-$(CONFIG_OF_MTD)	+= of_mtd.o
> > > +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> > > diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> > > new file mode 100644
> > > index 000000000000..f17cd56e68d9
> > > --- /dev/null
> > > +++ b/drivers/of/of_reserved_mem.c
> > > @@ -0,0 +1,219 @@
> > > +/*
> > > + * Device tree based initialization code for reserved memory.
> > > + *
> > > + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
> > > + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> > > + *		http://www.samsung.com
> > > + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
> > > + * Author: Josh Cartwright <joshc@codeaurora.org>
> > > + *
> > > + * This program is free software; you can redistribute it and/or
> > > + * modify it under the terms of the GNU General Public License as
> > > + * published by the Free Software Foundation; either version 2 of the
> > > + * License or (at your optional) any later version of the license.
> > > + */
> > > +#include <linux/memblock.h>
> > > +#include <linux/err.h>
> > > +#include <linux/of.h>
> > > +#include <linux/of_fdt.h>
> > > +#include <linux/of_platform.h>
> > > +#include <linux/mm.h>
> > > +#include <linux/sizes.h>
> > > +#include <linux/of_reserved_mem.h>
> > > +
> > > +#define MAX_RESERVED_REGIONS	16
> > > +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
> > > +static int reserved_mem_count;
> > > +
> > > +int __init of_parse_flat_dt_reg(unsigned long node, const char *uname,
> > > +				   phys_addr_t *base, phys_addr_t *size)
> >
> > Useful utility function; move to drivers/of/fdt.c
> >
> > > +{
> > > +	unsigned long len;
> > > +	__be32 *prop;
> > > +
> > > +	prop = of_get_flat_dt_prop(node, "reg", &len);
> > > +	if (!prop)
> > > +		return -EINVAL;
> > > +
> > > +	if (len < (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) {
> > > +		pr_err("Reserved memory: invalid reg property in '%s' node.\n",
> > > +				uname);
> > > +		return -EINVAL;
> > > +	}
> >
> > This is /okay/ for an initial implementation, but it is naive. While I
> > suggested making #address-cells and #size-cells equal the root node
> > values for the purpose of simplicity, it should still be perfectly valid
> > to have different values if the ranges property is correctly formed.
> >
> > > +
> > > +	*base = dt_mem_next_cell(dt_root_addr_cells, &prop);
> > > +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
> >
> > Future enhancement; allow for parsing more than just the first reg
> > tuple.
> 
> One more question. Does it really makes any sense to support more than
> one tuple for reg property? For consistency we should also allow more
> than one entry in size, align and alloc-ranges property, but I don't
> see any benefits for defining more than one range for a single region.
> Same can be achieved by defining more regions instead if one really
> needs such configuration.

Yes, if only because it is an define usage of the reg property. If a
devtree has multiple tuples in reg, then all of those tuples should be
treated as reserved, even if the kernel doesn't know how to use them.

I would not do the same for size/align/alloc-ranges unless there is a
very specific use case that you can define. These ones are different
from the static regions because they aren't ever used to protect
something that already exists in the memory.

g.

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

* Re: [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
  2014-02-11 12:13         ` Grant Likely
@ 2014-02-11 14:29           ` Tomasz Figa
  -1 siblings, 0 replies; 60+ messages in thread
From: Tomasz Figa @ 2014-02-11 14:29 UTC (permalink / raw)
  To: Grant Likely, Marek Szyprowski, linux-kernel, linux-arm-kernel,
	linaro-mm-sig, devicetree, linux-doc
  Cc: Kyungmin Park, Benjamin Herrenschmidt, Arnd Bergmann,
	Michal Nazarewicz, Sascha Hauer, Laura Abbott, Rob Herring,
	Olof Johansson, Pawel Moll, Mark Rutland, Stephen Warren,
	Ian Campbell, Tomasz Figa, Kumar Gala, Nishanth Peethambaran,
	Marc, Josh Cartwright

Hi,

On 11.02.2014 13:13, Grant Likely wrote:
> On Tue, 11 Feb 2014 12:45:50 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>> Hello,
>>
>> On 2014-02-05 12:05, Grant Likely wrote:
>>> On Tue, 04 Feb 2014 13:09:29 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>>>> This patch adds device tree support for contiguous and reserved memory
>>>> regions defined in device tree.
>>>>
>>>> Large memory blocks can be reliably reserved only during early boot.
>>>> This must happen before the whole memory management subsystem is
>>>> initialized, because we need to ensure that the given contiguous blocks
>>>> are not yet allocated by kernel. Also it must happen before kernel
>>>> mappings for the whole low memory are created, to ensure that there will
>>>> be no mappings (for reserved blocks) or mapping with special properties
>>>> can be created (for CMA blocks). This all happens before device tree
>>>> structures are unflattened, so we need to get reserved memory layout
>>>> directly from fdt.
>>>>
>>>> Later, those reserved memory regions are assigned to devices on each
>>>> device structure initialization.
>>>>
>>>> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>> Cc: Laura Abbott <lauraa@codeaurora.org>
>>>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>>> [joshc: rework to implement new DT binding, provide mechanism for
>>>>   plugging in new reserved-memory node handlers via
>>>>   RESERVEDMEM_OF_DECLARE]
>>>> Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
>>>> [mszyprow: little code cleanup]
>>>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>>> ---
>>>>   drivers/of/Kconfig                |    6 +
>>>>   drivers/of/Makefile               |    1 +
>>>>   drivers/of/of_reserved_mem.c      |  219 +++++++++++++++++++++++++++++++++++++
>>>>   drivers/of/platform.c             |    7 ++
>>>>   include/asm-generic/vmlinux.lds.h |   11 ++
>>>>   include/linux/of_reserved_mem.h   |   62 +++++++++++
>>>>   6 files changed, 306 insertions(+)
>>>>   create mode 100644 drivers/of/of_reserved_mem.c
>>>>   create mode 100644 include/linux/of_reserved_mem.h
>>>>
>>>> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
>>>> index c6973f101a3e..aba13df56f3a 100644
>>>> --- a/drivers/of/Kconfig
>>>> +++ b/drivers/of/Kconfig
>>>> @@ -75,4 +75,10 @@ config OF_MTD
>>>>   	depends on MTD
>>>>   	def_bool y
>>>>
>>>> +config OF_RESERVED_MEM
>>>> +	depends on HAVE_MEMBLOCK
>>>> +	def_bool y
>>>> +	help
>>>> +	  Helpers to allow for reservation of memory regions
>>>> +
>>>>   endmenu # OF
>>>> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
>>>> index efd05102c405..ed9660adad77 100644
>>>> --- a/drivers/of/Makefile
>>>> +++ b/drivers/of/Makefile
>>>> @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
>>>>   obj-$(CONFIG_OF_PCI)	+= of_pci.o
>>>>   obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
>>>>   obj-$(CONFIG_OF_MTD)	+= of_mtd.o
>>>> +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
>>>> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
>>>> new file mode 100644
>>>> index 000000000000..f17cd56e68d9
>>>> --- /dev/null
>>>> +++ b/drivers/of/of_reserved_mem.c
>>>> @@ -0,0 +1,219 @@
>>>> +/*
>>>> + * Device tree based initialization code for reserved memory.
>>>> + *
>>>> + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
>>>> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
>>>> + *		http://www.samsung.com
>>>> + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
>>>> + * Author: Josh Cartwright <joshc@codeaurora.org>
>>>> + *
>>>> + * This program is free software; you can redistribute it and/or
>>>> + * modify it under the terms of the GNU General Public License as
>>>> + * published by the Free Software Foundation; either version 2 of the
>>>> + * License or (at your optional) any later version of the license.
>>>> + */
>>>> +#include <linux/memblock.h>
>>>> +#include <linux/err.h>
>>>> +#include <linux/of.h>
>>>> +#include <linux/of_fdt.h>
>>>> +#include <linux/of_platform.h>
>>>> +#include <linux/mm.h>
>>>> +#include <linux/sizes.h>
>>>> +#include <linux/of_reserved_mem.h>
>>>> +
>>>> +#define MAX_RESERVED_REGIONS	16
>>>> +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
>>>> +static int reserved_mem_count;
>>>> +
>>>> +int __init of_parse_flat_dt_reg(unsigned long node, const char *uname,
>>>> +				   phys_addr_t *base, phys_addr_t *size)
>>>
>>> Useful utility function; move to drivers/of/fdt.c
>>>
>>>> +{
>>>> +	unsigned long len;
>>>> +	__be32 *prop;
>>>> +
>>>> +	prop = of_get_flat_dt_prop(node, "reg", &len);
>>>> +	if (!prop)
>>>> +		return -EINVAL;
>>>> +
>>>> +	if (len < (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) {
>>>> +		pr_err("Reserved memory: invalid reg property in '%s' node.\n",
>>>> +				uname);
>>>> +		return -EINVAL;
>>>> +	}
>>>
>>> This is /okay/ for an initial implementation, but it is naive. While I
>>> suggested making #address-cells and #size-cells equal the root node
>>> values for the purpose of simplicity, it should still be perfectly valid
>>> to have different values if the ranges property is correctly formed.
>>>
>>>> +
>>>> +	*base = dt_mem_next_cell(dt_root_addr_cells, &prop);
>>>> +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
>>>
>>> Future enhancement; allow for parsing more than just the first reg
>>> tuple.
>>
>> One more question. Does it really makes any sense to support more than
>> one tuple for reg property? For consistency we should also allow more
>> than one entry in size, align and alloc-ranges property, but I don't
>> see any benefits for defining more than one range for a single region.
>> Same can be achieved by defining more regions instead if one really
>> needs such configuration.
>
> Yes, if only because it is an define usage of the reg property. If a
> devtree has multiple tuples in reg, then all of those tuples should be
> treated as reserved, even if the kernel doesn't know how to use them.
>
> I would not do the same for size/align/alloc-ranges unless there is a
> very specific use case that you can define. These ones are different
> from the static regions because they aren't ever used to protect
> something that already exists in the memory.

Is there a reason why multiple regions could not be used for this 
purpose, instead of adding extra complexity of having multiple reg 
entries per region?

I.e. I don't see a difference between

reg1: region@00000000 {
	reg = <0x00000000 0x1000>;
};

reg2: region@10000000 {
	reg = <0x10000000 0x1000>;
};

user {
	regions = <&reg1>, <&reg2>;
};

and

reg: region@00000000 {
	reg = <0x00000000 0x1000>, <0x10000000 0x1000>;
};

user {
	regions = <&reg>;
};

except that the former IMHO better suits the definition of memory 
region, which I see as a single contiguous range of memory and can be 
simplified to have a single reg entry per region.

Best regards,
Tomasz

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

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-11 14:29           ` Tomasz Figa
  0 siblings, 0 replies; 60+ messages in thread
From: Tomasz Figa @ 2014-02-11 14:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 11.02.2014 13:13, Grant Likely wrote:
> On Tue, 11 Feb 2014 12:45:50 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>> Hello,
>>
>> On 2014-02-05 12:05, Grant Likely wrote:
>>> On Tue, 04 Feb 2014 13:09:29 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>>>> This patch adds device tree support for contiguous and reserved memory
>>>> regions defined in device tree.
>>>>
>>>> Large memory blocks can be reliably reserved only during early boot.
>>>> This must happen before the whole memory management subsystem is
>>>> initialized, because we need to ensure that the given contiguous blocks
>>>> are not yet allocated by kernel. Also it must happen before kernel
>>>> mappings for the whole low memory are created, to ensure that there will
>>>> be no mappings (for reserved blocks) or mapping with special properties
>>>> can be created (for CMA blocks). This all happens before device tree
>>>> structures are unflattened, so we need to get reserved memory layout
>>>> directly from fdt.
>>>>
>>>> Later, those reserved memory regions are assigned to devices on each
>>>> device structure initialization.
>>>>
>>>> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>> Cc: Laura Abbott <lauraa@codeaurora.org>
>>>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>>> [joshc: rework to implement new DT binding, provide mechanism for
>>>>   plugging in new reserved-memory node handlers via
>>>>   RESERVEDMEM_OF_DECLARE]
>>>> Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
>>>> [mszyprow: little code cleanup]
>>>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>>> ---
>>>>   drivers/of/Kconfig                |    6 +
>>>>   drivers/of/Makefile               |    1 +
>>>>   drivers/of/of_reserved_mem.c      |  219 +++++++++++++++++++++++++++++++++++++
>>>>   drivers/of/platform.c             |    7 ++
>>>>   include/asm-generic/vmlinux.lds.h |   11 ++
>>>>   include/linux/of_reserved_mem.h   |   62 +++++++++++
>>>>   6 files changed, 306 insertions(+)
>>>>   create mode 100644 drivers/of/of_reserved_mem.c
>>>>   create mode 100644 include/linux/of_reserved_mem.h
>>>>
>>>> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
>>>> index c6973f101a3e..aba13df56f3a 100644
>>>> --- a/drivers/of/Kconfig
>>>> +++ b/drivers/of/Kconfig
>>>> @@ -75,4 +75,10 @@ config OF_MTD
>>>>   	depends on MTD
>>>>   	def_bool y
>>>>
>>>> +config OF_RESERVED_MEM
>>>> +	depends on HAVE_MEMBLOCK
>>>> +	def_bool y
>>>> +	help
>>>> +	  Helpers to allow for reservation of memory regions
>>>> +
>>>>   endmenu # OF
>>>> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
>>>> index efd05102c405..ed9660adad77 100644
>>>> --- a/drivers/of/Makefile
>>>> +++ b/drivers/of/Makefile
>>>> @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
>>>>   obj-$(CONFIG_OF_PCI)	+= of_pci.o
>>>>   obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
>>>>   obj-$(CONFIG_OF_MTD)	+= of_mtd.o
>>>> +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
>>>> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
>>>> new file mode 100644
>>>> index 000000000000..f17cd56e68d9
>>>> --- /dev/null
>>>> +++ b/drivers/of/of_reserved_mem.c
>>>> @@ -0,0 +1,219 @@
>>>> +/*
>>>> + * Device tree based initialization code for reserved memory.
>>>> + *
>>>> + * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
>>>> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
>>>> + *		http://www.samsung.com
>>>> + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
>>>> + * Author: Josh Cartwright <joshc@codeaurora.org>
>>>> + *
>>>> + * This program is free software; you can redistribute it and/or
>>>> + * modify it under the terms of the GNU General Public License as
>>>> + * published by the Free Software Foundation; either version 2 of the
>>>> + * License or (at your optional) any later version of the license.
>>>> + */
>>>> +#include <linux/memblock.h>
>>>> +#include <linux/err.h>
>>>> +#include <linux/of.h>
>>>> +#include <linux/of_fdt.h>
>>>> +#include <linux/of_platform.h>
>>>> +#include <linux/mm.h>
>>>> +#include <linux/sizes.h>
>>>> +#include <linux/of_reserved_mem.h>
>>>> +
>>>> +#define MAX_RESERVED_REGIONS	16
>>>> +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
>>>> +static int reserved_mem_count;
>>>> +
>>>> +int __init of_parse_flat_dt_reg(unsigned long node, const char *uname,
>>>> +				   phys_addr_t *base, phys_addr_t *size)
>>>
>>> Useful utility function; move to drivers/of/fdt.c
>>>
>>>> +{
>>>> +	unsigned long len;
>>>> +	__be32 *prop;
>>>> +
>>>> +	prop = of_get_flat_dt_prop(node, "reg", &len);
>>>> +	if (!prop)
>>>> +		return -EINVAL;
>>>> +
>>>> +	if (len < (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) {
>>>> +		pr_err("Reserved memory: invalid reg property in '%s' node.\n",
>>>> +				uname);
>>>> +		return -EINVAL;
>>>> +	}
>>>
>>> This is /okay/ for an initial implementation, but it is naive. While I
>>> suggested making #address-cells and #size-cells equal the root node
>>> values for the purpose of simplicity, it should still be perfectly valid
>>> to have different values if the ranges property is correctly formed.
>>>
>>>> +
>>>> +	*base = dt_mem_next_cell(dt_root_addr_cells, &prop);
>>>> +	*size = dt_mem_next_cell(dt_root_size_cells, &prop);
>>>
>>> Future enhancement; allow for parsing more than just the first reg
>>> tuple.
>>
>> One more question. Does it really makes any sense to support more than
>> one tuple for reg property? For consistency we should also allow more
>> than one entry in size, align and alloc-ranges property, but I don't
>> see any benefits for defining more than one range for a single region.
>> Same can be achieved by defining more regions instead if one really
>> needs such configuration.
>
> Yes, if only because it is an define usage of the reg property. If a
> devtree has multiple tuples in reg, then all of those tuples should be
> treated as reserved, even if the kernel doesn't know how to use them.
>
> I would not do the same for size/align/alloc-ranges unless there is a
> very specific use case that you can define. These ones are different
> from the static regions because they aren't ever used to protect
> something that already exists in the memory.

Is there a reason why multiple regions could not be used for this 
purpose, instead of adding extra complexity of having multiple reg 
entries per region?

I.e. I don't see a difference between

reg1: region at 00000000 {
	reg = <0x00000000 0x1000>;
};

reg2: region at 10000000 {
	reg = <0x10000000 0x1000>;
};

user {
	regions = <&reg1>, <&reg2>;
};

and

reg: region at 00000000 {
	reg = <0x00000000 0x1000>, <0x10000000 0x1000>;
};

user {
	regions = <&reg>;
};

except that the former IMHO better suits the definition of memory 
region, which I see as a single contiguous range of memory and can be 
simplified to have a single reg entry per region.

Best regards,
Tomasz

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

* Re: [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-11 19:01             ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-11 19:01 UTC (permalink / raw)
  To: Tomasz Figa, Marek Szyprowski, linux-kernel, linux-arm-kernel,
	linaro-mm-sig, devicetree, linux-doc
  Cc: Kyungmin Park, Benjamin Herrenschmidt, Arnd Bergmann,
	Michal Nazarewicz, Sascha Hauer, Laura Abbott, Rob Herring,
	Olof Johansson, Pawel Moll, Mark Rutland, Stephen Warren,
	Ian Campbell, Tomasz Figa, Kumar Gala, Nishanth Peethambaran,
	Marc, Josh Cartwright

On Tue, 11 Feb 2014 15:29:54 +0100, Tomasz Figa <t.figa@samsung.com> wrote:
> > Yes, if only because it is an define usage of the reg property. If a
> > devtree has multiple tuples in reg, then all of those tuples should be
> > treated as reserved, even if the kernel doesn't know how to use them.
> >
> > I would not do the same for size/align/alloc-ranges unless there is a
> > very specific use case that you can define. These ones are different
> > from the static regions because they aren't ever used to protect
> > something that already exists in the memory.
> 
> Is there a reason why multiple regions could not be used for this 
> purpose, instead of adding extra complexity of having multiple reg 
> entries per region?
> 
> I.e. I don't see a difference between
> 
> reg1: region@00000000 {
> 	reg = <0x00000000 0x1000>;
> };
> 
> reg2: region@10000000 {
> 	reg = <0x10000000 0x1000>;
> };
> 
> user {
> 	regions = <&reg1>, <&reg2>;
> };
> 
> and
> 
> reg: region@00000000 {
> 	reg = <0x00000000 0x1000>, <0x10000000 0x1000>;
> };
> 
> user {
> 	regions = <&reg>;
> };
> 
> except that the former IMHO better suits the definition of memory 
> region, which I see as a single contiguous range of memory and can be 
> simplified to have a single reg entry per region.

My point is rather if multiple reg tuples are found in a reserved memory
node, the kernel must respect them and reserve the memory. I'm not
arguing about whether or not that makes for a good binding.

g.


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

* Re: [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-11 19:01             ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-11 19:01 UTC (permalink / raw)
  To: Tomasz Figa, Marek Szyprowski,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA
  Cc: Kyungmin Park, Benjamin Herrenschmidt, Arnd Bergmann,
	Michal Nazarewicz, Sascha Hauer, Laura Abbott, Rob Herring,
	Olof Johansson, Pawel Moll, Mark Rutland, Stephen Warren,
	Ian Campbell, Tomasz Figa, Kumar Gala, Nishanth Peethambaran,
	Marc, Josh Cartwright

On Tue, 11 Feb 2014 15:29:54 +0100, Tomasz Figa <t.figa-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
> > Yes, if only because it is an define usage of the reg property. If a
> > devtree has multiple tuples in reg, then all of those tuples should be
> > treated as reserved, even if the kernel doesn't know how to use them.
> >
> > I would not do the same for size/align/alloc-ranges unless there is a
> > very specific use case that you can define. These ones are different
> > from the static regions because they aren't ever used to protect
> > something that already exists in the memory.
> 
> Is there a reason why multiple regions could not be used for this 
> purpose, instead of adding extra complexity of having multiple reg 
> entries per region?
> 
> I.e. I don't see a difference between
> 
> reg1: region@00000000 {
> 	reg = <0x00000000 0x1000>;
> };
> 
> reg2: region@10000000 {
> 	reg = <0x10000000 0x1000>;
> };
> 
> user {
> 	regions = <&reg1>, <&reg2>;
> };
> 
> and
> 
> reg: region@00000000 {
> 	reg = <0x00000000 0x1000>, <0x10000000 0x1000>;
> };
> 
> user {
> 	regions = <&reg>;
> };
> 
> except that the former IMHO better suits the definition of memory 
> region, which I see as a single contiguous range of memory and can be 
> simplified to have a single reg entry per region.

My point is rather if multiple reg tuples are found in a reserved memory
node, the kernel must respect them and reserve the memory. I'm not
arguing about whether or not that makes for a good binding.

g.

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-11 19:01             ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-11 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 11 Feb 2014 15:29:54 +0100, Tomasz Figa <t.figa@samsung.com> wrote:
> > Yes, if only because it is an define usage of the reg property. If a
> > devtree has multiple tuples in reg, then all of those tuples should be
> > treated as reserved, even if the kernel doesn't know how to use them.
> >
> > I would not do the same for size/align/alloc-ranges unless there is a
> > very specific use case that you can define. These ones are different
> > from the static regions because they aren't ever used to protect
> > something that already exists in the memory.
> 
> Is there a reason why multiple regions could not be used for this 
> purpose, instead of adding extra complexity of having multiple reg 
> entries per region?
> 
> I.e. I don't see a difference between
> 
> reg1: region at 00000000 {
> 	reg = <0x00000000 0x1000>;
> };
> 
> reg2: region at 10000000 {
> 	reg = <0x10000000 0x1000>;
> };
> 
> user {
> 	regions = <&reg1>, <&reg2>;
> };
> 
> and
> 
> reg: region at 00000000 {
> 	reg = <0x00000000 0x1000>, <0x10000000 0x1000>;
> };
> 
> user {
> 	regions = <&reg>;
> };
> 
> except that the former IMHO better suits the definition of memory 
> region, which I see as a single contiguous range of memory and can be 
> simplified to have a single reg entry per region.

My point is rather if multiple reg tuples are found in a reserved memory
node, the kernel must respect them and reserve the memory. I'm not
arguing about whether or not that makes for a good binding.

g.

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

* Re: [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
  2014-02-11 19:01             ` Grant Likely
@ 2014-02-11 20:02               ` Benjamin Herrenschmidt
  -1 siblings, 0 replies; 60+ messages in thread
From: Benjamin Herrenschmidt @ 2014-02-11 20:02 UTC (permalink / raw)
  To: Grant Likely
  Cc: Tomasz Figa, Marek Szyprowski, linux-kernel, linux-arm-kernel,
	linaro-mm-sig, devicetree, linux-doc, Kyungmin Park,
	Arnd Bergmann, Michal Nazarewicz, Sascha Hauer, Laura Abbott,
	Rob Herring, Olof Johansson, Pawel Moll, Mark Rutland,
	Stephen Warren, Ian Campbell, Tomasz Figa, Kumar Gala,
	Nishanth Peethambaran, Marc, Josh Cartwright

On Tue, 2014-02-11 at 19:01 +0000, Grant Likely wrote:

> > except that the former IMHO better suits the definition of memory 
> > region, which I see as a single contiguous range of memory and can be 
> > simplified to have a single reg entry per region.
> 
> My point is rather if multiple reg tuples are found in a reserved memory
> node, the kernel must respect them and reserve the memory. I'm not
> arguing about whether or not that makes for a good binding.

agreed.

Cheers,
Ben.



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

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-11 20:02               ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 60+ messages in thread
From: Benjamin Herrenschmidt @ 2014-02-11 20:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2014-02-11 at 19:01 +0000, Grant Likely wrote:

> > except that the former IMHO better suits the definition of memory 
> > region, which I see as a single contiguous range of memory and can be 
> > simplified to have a single reg entry per region.
> 
> My point is rather if multiple reg tuples are found in a reserved memory
> node, the kernel must respect them and reserve the memory. I'm not
> arguing about whether or not that makes for a good binding.

agreed.

Cheers,
Ben.

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

* Re: [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
  2014-02-11 20:02               ` Benjamin Herrenschmidt
@ 2014-02-11 20:04                 ` Tomasz Figa
  -1 siblings, 0 replies; 60+ messages in thread
From: Tomasz Figa @ 2014-02-11 20:04 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Grant Likely
  Cc: Tomasz Figa, Marek Szyprowski, linux-kernel, linux-arm-kernel,
	linaro-mm-sig, devicetree, linux-doc, Kyungmin Park,
	Arnd Bergmann, Michal Nazarewicz, Sascha Hauer, Laura Abbott,
	Rob Herring, Olof Johansson, Pawel Moll, Mark Rutland,
	Stephen Warren, Ian Campbell, Kumar Gala, Nishanth Peethambaran,
	Marc, Josh Cartwright



On 11.02.2014 21:02, Benjamin Herrenschmidt wrote:
> On Tue, 2014-02-11 at 19:01 +0000, Grant Likely wrote:
>
>>> except that the former IMHO better suits the definition of memory
>>> region, which I see as a single contiguous range of memory and can be
>>> simplified to have a single reg entry per region.
>>
>> My point is rather if multiple reg tuples are found in a reserved memory
>> node, the kernel must respect them and reserve the memory. I'm not
>> arguing about whether or not that makes for a good binding.
>
> agreed.

My point is why, if the binding defines that just a single tuple should 
be provided.

Best regards,
Tomasz

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

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-11 20:04                 ` Tomasz Figa
  0 siblings, 0 replies; 60+ messages in thread
From: Tomasz Figa @ 2014-02-11 20:04 UTC (permalink / raw)
  To: linux-arm-kernel



On 11.02.2014 21:02, Benjamin Herrenschmidt wrote:
> On Tue, 2014-02-11 at 19:01 +0000, Grant Likely wrote:
>
>>> except that the former IMHO better suits the definition of memory
>>> region, which I see as a single contiguous range of memory and can be
>>> simplified to have a single reg entry per region.
>>
>> My point is rather if multiple reg tuples are found in a reserved memory
>> node, the kernel must respect them and reserve the memory. I'm not
>> arguing about whether or not that makes for a good binding.
>
> agreed.

My point is why, if the binding defines that just a single tuple should 
be provided.

Best regards,
Tomasz

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

* Re: [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
  2014-02-11 20:04                 ` Tomasz Figa
@ 2014-02-11 20:19                   ` Josh Cartwright
  -1 siblings, 0 replies; 60+ messages in thread
From: Josh Cartwright @ 2014-02-11 20:19 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Benjamin Herrenschmidt, Grant Likely, Tomasz Figa,
	Marek Szyprowski, linux-kernel, linux-arm-kernel, linaro-mm-sig,
	devicetree, linux-doc, Kyungmin Park, Arnd Bergmann,
	Michal Nazarewicz, Sascha Hauer, Laura Abbott, Rob Herring,
	Olof Johansson, Pawel Moll, Mark Rutland, Stephen Warren,
	Ian Campbell, Kumar Gala, Nishanth Peethambaran, Marc

On Tue, Feb 11, 2014 at 09:04:21PM +0100, Tomasz Figa wrote:
> 
> 
> On 11.02.2014 21:02, Benjamin Herrenschmidt wrote:
> >On Tue, 2014-02-11 at 19:01 +0000, Grant Likely wrote:
> >
> >>>except that the former IMHO better suits the definition of memory
> >>>region, which I see as a single contiguous range of memory and can be
> >>>simplified to have a single reg entry per region.
> >>
> >>My point is rather if multiple reg tuples are found in a reserved memory
> >>node, the kernel must respect them and reserve the memory. I'm not
> >>arguing about whether or not that makes for a good binding.
> >
> >agreed.
> 
> My point is why, if the binding defines that just a single tuple should be
> provided.

FWIW, the usecase I had mentioned in reply to Grant in the patch 5/5
thread [1] could make use of this.  The shared memory region is split
into a main chunk and several "auxiliary" chunk, but collectively these
regions all share the same heap state.

  Josh

1: http://lkml.kernel.org/r/20140205192502.GO20228@joshc.qualcomm.com

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-11 20:19                   ` Josh Cartwright
  0 siblings, 0 replies; 60+ messages in thread
From: Josh Cartwright @ 2014-02-11 20:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 11, 2014 at 09:04:21PM +0100, Tomasz Figa wrote:
> 
> 
> On 11.02.2014 21:02, Benjamin Herrenschmidt wrote:
> >On Tue, 2014-02-11 at 19:01 +0000, Grant Likely wrote:
> >
> >>>except that the former IMHO better suits the definition of memory
> >>>region, which I see as a single contiguous range of memory and can be
> >>>simplified to have a single reg entry per region.
> >>
> >>My point is rather if multiple reg tuples are found in a reserved memory
> >>node, the kernel must respect them and reserve the memory. I'm not
> >>arguing about whether or not that makes for a good binding.
> >
> >agreed.
> 
> My point is why, if the binding defines that just a single tuple should be
> provided.

FWIW, the usecase I had mentioned in reply to Grant in the patch 5/5
thread [1] could make use of this.  The shared memory region is split
into a main chunk and several "auxiliary" chunk, but collectively these
regions all share the same heap state.

  Josh

1: http://lkml.kernel.org/r/20140205192502.GO20228 at joshc.qualcomm.com

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* Re: [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
  2014-02-11 20:19                   ` Josh Cartwright
@ 2014-02-11 20:27                     ` Tomasz Figa
  -1 siblings, 0 replies; 60+ messages in thread
From: Tomasz Figa @ 2014-02-11 20:27 UTC (permalink / raw)
  To: Josh Cartwright
  Cc: Benjamin Herrenschmidt, Grant Likely, Tomasz Figa,
	Marek Szyprowski, linux-kernel, linux-arm-kernel, linaro-mm-sig,
	devicetree, linux-doc, Kyungmin Park, Arnd Bergmann,
	Michal Nazarewicz, Sascha Hauer, Laura Abbott, Rob Herring,
	Olof Johansson, Pawel Moll, Mark Rutland, Stephen Warren,
	Ian Campbell, Kumar Gala, Nishanth Peethambaran, Marc



On 11.02.2014 21:19, Josh Cartwright wrote:
> On Tue, Feb 11, 2014 at 09:04:21PM +0100, Tomasz Figa wrote:
>>
>>
>> On 11.02.2014 21:02, Benjamin Herrenschmidt wrote:
>>> On Tue, 2014-02-11 at 19:01 +0000, Grant Likely wrote:
>>>
>>>>> except that the former IMHO better suits the definition of memory
>>>>> region, which I see as a single contiguous range of memory and can be
>>>>> simplified to have a single reg entry per region.
>>>>
>>>> My point is rather if multiple reg tuples are found in a reserved memory
>>>> node, the kernel must respect them and reserve the memory. I'm not
>>>> arguing about whether or not that makes for a good binding.
>>>
>>> agreed.
>>
>> My point is why, if the binding defines that just a single tuple should be
>> provided.
>
> FWIW, the usecase I had mentioned in reply to Grant in the patch 5/5
> thread [1] could make use of this.  The shared memory region is split
> into a main chunk and several "auxiliary" chunk, but collectively these
> regions all share the same heap state.
>
>    Josh
>
> 1: http://lkml.kernel.org/r/20140205192502.GO20228@joshc.qualcomm.com
>

The use case seems fine, but I believe it could be properly represented 
in device tree using multiple single-reg regions as well, unless the 
consumer can request a block of memory that crosses boundary of two 
sub-regions specified by reg entries of single region.

Best regards,
Tomasz

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

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-11 20:27                     ` Tomasz Figa
  0 siblings, 0 replies; 60+ messages in thread
From: Tomasz Figa @ 2014-02-11 20:27 UTC (permalink / raw)
  To: linux-arm-kernel



On 11.02.2014 21:19, Josh Cartwright wrote:
> On Tue, Feb 11, 2014 at 09:04:21PM +0100, Tomasz Figa wrote:
>>
>>
>> On 11.02.2014 21:02, Benjamin Herrenschmidt wrote:
>>> On Tue, 2014-02-11 at 19:01 +0000, Grant Likely wrote:
>>>
>>>>> except that the former IMHO better suits the definition of memory
>>>>> region, which I see as a single contiguous range of memory and can be
>>>>> simplified to have a single reg entry per region.
>>>>
>>>> My point is rather if multiple reg tuples are found in a reserved memory
>>>> node, the kernel must respect them and reserve the memory. I'm not
>>>> arguing about whether or not that makes for a good binding.
>>>
>>> agreed.
>>
>> My point is why, if the binding defines that just a single tuple should be
>> provided.
>
> FWIW, the usecase I had mentioned in reply to Grant in the patch 5/5
> thread [1] could make use of this.  The shared memory region is split
> into a main chunk and several "auxiliary" chunk, but collectively these
> regions all share the same heap state.
>
>    Josh
>
> 1: http://lkml.kernel.org/r/20140205192502.GO20228 at joshc.qualcomm.com
>

The use case seems fine, but I believe it could be properly represented 
in device tree using multiple single-reg regions as well, unless the 
consumer can request a block of memory that crosses boundary of two 
sub-regions specified by reg entries of single region.

Best regards,
Tomasz

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

* Re: [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
  2014-02-11 20:27                     ` Tomasz Figa
@ 2014-02-13 19:48                       ` Josh Cartwright
  -1 siblings, 0 replies; 60+ messages in thread
From: Josh Cartwright @ 2014-02-13 19:48 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Benjamin Herrenschmidt, Grant Likely, Tomasz Figa,
	Marek Szyprowski, linux-kernel, linux-arm-kernel, linaro-mm-sig,
	devicetree, linux-doc, Kyungmin Park, Arnd Bergmann,
	Michal Nazarewicz, Sascha Hauer, Laura Abbott, Rob Herring,
	Olof Johansson, Pawel Moll, Mark Rutland, Stephen Warren,
	Ian Campbell, Kumar Gala, Nishanth Peethambaran, Marc

On Tue, Feb 11, 2014 at 09:27:36PM +0100, Tomasz Figa wrote:
> On 11.02.2014 21:19, Josh Cartwright wrote:
> >On Tue, Feb 11, 2014 at 09:04:21PM +0100, Tomasz Figa wrote:
> > >On 11.02.2014 21:02, Benjamin Herrenschmidt wrote:
> > > >On Tue, 2014-02-11 at 19:01 +0000, Grant Likely wrote:
> > > > > > except that the former IMHO better suits the definition of memory
> > > > > > region, which I see as a single contiguous range of memory and can be
> > > > > > simplified to have a single reg entry per region.
> > > > >
> > > > > My point is rather if multiple reg tuples are found in a reserved memory
> > > > > node, the kernel must respect them and reserve the memory. I'm not
> > > > > arguing about whether or not that makes for a good binding.
> > > >
> > > > agreed.
> > >
> > > My point is why, if the binding defines that just a single tuple should be
> > > provided.
> >
> > FWIW, the usecase I had mentioned in reply to Grant in the patch 5/5
> > thread [1] could make use of this.  The shared memory region is split
> > into a main chunk and several "auxiliary" chunk, but collectively these
> > regions all share the same heap state.
> >
> >   Josh
> >
> > 1: http://lkml.kernel.org/r/20140205192502.GO20228@joshc.qualcomm.com
>
> The use case seems fine, but I believe it could be properly represented in
> device tree using multiple single-reg regions as well, unless the consumer
> can request a block of memory that crosses boundary of two sub-regions
> specified by reg entries of single region.

I could probably make a only-one-reg-entry policy work for me, but it
makes things a bit more awkward.  I'd lose the ability to describe
"this set of regions need to be logically handled together" directly in
the reserved memory node, and would need to push it up a layer.

	reserved-memory {
		smem: smem {
			reg = <...>;
		};
		aux1: auxiliary1 {
			reg = <...>;
		};
		aux2: auxiliary2 {
			reg = <...>;
		};
		...
	};

	heap : heap {
		compatible = "qcom,shared-memory";
		memory-region = <&smem &aux1 &aux2>;
		#smem-cells = <2>;
	};

	actual_consumer1 {
		compatible = "...";
		smem = <&heap IDENTIFIER1 0x1000>;
	};

	actual_consumer2 {
		compatible = "...";
		smem = <&heap IDENTIFIER2 0x1000>;
	};

Maybe that's better off, I don't know.  This would also eliminate my
need for a #memory-region-cells property.

Thanks,
  Josh

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-13 19:48                       ` Josh Cartwright
  0 siblings, 0 replies; 60+ messages in thread
From: Josh Cartwright @ 2014-02-13 19:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 11, 2014 at 09:27:36PM +0100, Tomasz Figa wrote:
> On 11.02.2014 21:19, Josh Cartwright wrote:
> >On Tue, Feb 11, 2014 at 09:04:21PM +0100, Tomasz Figa wrote:
> > >On 11.02.2014 21:02, Benjamin Herrenschmidt wrote:
> > > >On Tue, 2014-02-11 at 19:01 +0000, Grant Likely wrote:
> > > > > > except that the former IMHO better suits the definition of memory
> > > > > > region, which I see as a single contiguous range of memory and can be
> > > > > > simplified to have a single reg entry per region.
> > > > >
> > > > > My point is rather if multiple reg tuples are found in a reserved memory
> > > > > node, the kernel must respect them and reserve the memory. I'm not
> > > > > arguing about whether or not that makes for a good binding.
> > > >
> > > > agreed.
> > >
> > > My point is why, if the binding defines that just a single tuple should be
> > > provided.
> >
> > FWIW, the usecase I had mentioned in reply to Grant in the patch 5/5
> > thread [1] could make use of this.  The shared memory region is split
> > into a main chunk and several "auxiliary" chunk, but collectively these
> > regions all share the same heap state.
> >
> >   Josh
> >
> > 1: http://lkml.kernel.org/r/20140205192502.GO20228 at joshc.qualcomm.com
>
> The use case seems fine, but I believe it could be properly represented in
> device tree using multiple single-reg regions as well, unless the consumer
> can request a block of memory that crosses boundary of two sub-regions
> specified by reg entries of single region.

I could probably make a only-one-reg-entry policy work for me, but it
makes things a bit more awkward.  I'd lose the ability to describe
"this set of regions need to be logically handled together" directly in
the reserved memory node, and would need to push it up a layer.

	reserved-memory {
		smem: smem {
			reg = <...>;
		};
		aux1: auxiliary1 {
			reg = <...>;
		};
		aux2: auxiliary2 {
			reg = <...>;
		};
		...
	};

	heap : heap {
		compatible = "qcom,shared-memory";
		memory-region = <&smem &aux1 &aux2>;
		#smem-cells = <2>;
	};

	actual_consumer1 {
		compatible = "...";
		smem = <&heap IDENTIFIER1 0x1000>;
	};

	actual_consumer2 {
		compatible = "...";
		smem = <&heap IDENTIFIER2 0x1000>;
	};

Maybe that's better off, I don't know.  This would also eliminate my
need for a #memory-region-cells property.

Thanks,
  Josh

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* Re: [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
  2014-02-11 20:04                 ` Tomasz Figa
@ 2014-02-17 16:47                   ` Grant Likely
  -1 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-17 16:47 UTC (permalink / raw)
  To: Tomasz Figa, Benjamin Herrenschmidt
  Cc: Tomasz Figa, Marek Szyprowski, linux-kernel, linux-arm-kernel,
	linaro-mm-sig, devicetree, linux-doc, Kyungmin Park,
	Arnd Bergmann, Michal Nazarewicz, Sascha Hauer, Laura Abbott,
	Rob Herring, Olof Johansson, Pawel Moll, Mark Rutland,
	Stephen Warren, Ian Campbell, Kumar Gala, Nishanth Peethambaran,
	Marc, Josh Cartwright

On Tue, 11 Feb 2014 21:04:21 +0100, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> 
> 
> On 11.02.2014 21:02, Benjamin Herrenschmidt wrote:
> > On Tue, 2014-02-11 at 19:01 +0000, Grant Likely wrote:
> >
> >>> except that the former IMHO better suits the definition of memory
> >>> region, which I see as a single contiguous range of memory and can be
> >>> simplified to have a single reg entry per region.
> >>
> >> My point is rather if multiple reg tuples are found in a reserved memory
> >> node, the kernel must respect them and reserve the memory. I'm not
> >> arguing about whether or not that makes for a good binding.
> >
> > agreed.
> 
> My point is why, if the binding defines that just a single tuple should 
> be provided.

It's irrelevant because it gets processed at a different level. It's
important that the core early setup code can quickly parse all the
reserved regions without having any idea what the end-user binding is.
Multiple reg tuples is just fine in this regard.

Whether or not multiple tuples makes sense is defined for each
particular use case by the driver actually using it without impacting
core initialization code one iota.

g.

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

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-17 16:47                   ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-17 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 11 Feb 2014 21:04:21 +0100, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> 
> 
> On 11.02.2014 21:02, Benjamin Herrenschmidt wrote:
> > On Tue, 2014-02-11 at 19:01 +0000, Grant Likely wrote:
> >
> >>> except that the former IMHO better suits the definition of memory
> >>> region, which I see as a single contiguous range of memory and can be
> >>> simplified to have a single reg entry per region.
> >>
> >> My point is rather if multiple reg tuples are found in a reserved memory
> >> node, the kernel must respect them and reserve the memory. I'm not
> >> arguing about whether or not that makes for a good binding.
> >
> > agreed.
> 
> My point is why, if the binding defines that just a single tuple should 
> be provided.

It's irrelevant because it gets processed at a different level. It's
important that the core early setup code can quickly parse all the
reserved regions without having any idea what the end-user binding is.
Multiple reg tuples is just fine in this regard.

Whether or not multiple tuples makes sense is defined for each
particular use case by the driver actually using it without impacting
core initialization code one iota.

g.

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

* Re: [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
  2014-02-13 19:48                       ` Josh Cartwright
@ 2014-02-17 16:53                         ` Grant Likely
  -1 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-17 16:53 UTC (permalink / raw)
  To: Josh Cartwright, Tomasz Figa
  Cc: Benjamin Herrenschmidt, Tomasz Figa, Marek Szyprowski,
	linux-kernel, linux-arm-kernel, linaro-mm-sig, devicetree,
	linux-doc, Kyungmin Park, Arnd Bergmann, Michal Nazarewicz,
	Sascha Hauer, Laura Abbott, Rob Herring, Olof Johansson,
	Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
	Kumar Gala, Nishanth Peethambaran, Marc

On Thu, 13 Feb 2014 13:48:40 -0600, Josh Cartwright <joshc@codeaurora.org> wrote:
> On Tue, Feb 11, 2014 at 09:27:36PM +0100, Tomasz Figa wrote:
> > On 11.02.2014 21:19, Josh Cartwright wrote:
> > >On Tue, Feb 11, 2014 at 09:04:21PM +0100, Tomasz Figa wrote:
> > > >On 11.02.2014 21:02, Benjamin Herrenschmidt wrote:
> > > > >On Tue, 2014-02-11 at 19:01 +0000, Grant Likely wrote:
> > > > > > > except that the former IMHO better suits the definition of memory
> > > > > > > region, which I see as a single contiguous range of memory and can be
> > > > > > > simplified to have a single reg entry per region.
> > > > > >
> > > > > > My point is rather if multiple reg tuples are found in a reserved memory
> > > > > > node, the kernel must respect them and reserve the memory. I'm not
> > > > > > arguing about whether or not that makes for a good binding.
> > > > >
> > > > > agreed.
> > > >
> > > > My point is why, if the binding defines that just a single tuple should be
> > > > provided.
> > >
> > > FWIW, the usecase I had mentioned in reply to Grant in the patch 5/5
> > > thread [1] could make use of this.  The shared memory region is split
> > > into a main chunk and several "auxiliary" chunk, but collectively these
> > > regions all share the same heap state.
> > >
> > >   Josh
> > >
> > > 1: http://lkml.kernel.org/r/20140205192502.GO20228@joshc.qualcomm.com
> >
> > The use case seems fine, but I believe it could be properly represented in
> > device tree using multiple single-reg regions as well, unless the consumer
> > can request a block of memory that crosses boundary of two sub-regions
> > specified by reg entries of single region.
> 
> I could probably make a only-one-reg-entry policy work for me, but it
> makes things a bit more awkward.  I'd lose the ability to describe
> "this set of regions need to be logically handled together" directly in
> the reserved memory node, and would need to push it up a layer.
> 
> 	reserved-memory {
> 		smem: smem {
> 			reg = <...>;
> 		};
> 		aux1: auxiliary1 {
> 			reg = <...>;
> 		};
> 		aux2: auxiliary2 {
> 			reg = <...>;
> 		};
> 		...
> 	};

If the regions are used for different purposes, it makes sense I think
to have a separate node for each. Multiple tuples would make more sense
for something like valid DMA regions for a broken device that can only
DMA into a few windows; you could have one tuple per window within a
single node.

It would be possible to collect multiple associated nodes under one
parent node which in turn has reserved-memory for its parent:

	reserved-memory {
		ranges;
		reserved-group {
			ranges;
			smem: smem {
				reg = <...>;
			};
			aux1: auxiliary1 {
				reg = <...>;
			};
			aux2: auxiliary2 {
				reg = <...>;
			};
		};
		...
	};

g.

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

* [PATCH v2 1/5] drivers: of: add initialization code for reserved memory
@ 2014-02-17 16:53                         ` Grant Likely
  0 siblings, 0 replies; 60+ messages in thread
From: Grant Likely @ 2014-02-17 16:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 13 Feb 2014 13:48:40 -0600, Josh Cartwright <joshc@codeaurora.org> wrote:
> On Tue, Feb 11, 2014 at 09:27:36PM +0100, Tomasz Figa wrote:
> > On 11.02.2014 21:19, Josh Cartwright wrote:
> > >On Tue, Feb 11, 2014 at 09:04:21PM +0100, Tomasz Figa wrote:
> > > >On 11.02.2014 21:02, Benjamin Herrenschmidt wrote:
> > > > >On Tue, 2014-02-11 at 19:01 +0000, Grant Likely wrote:
> > > > > > > except that the former IMHO better suits the definition of memory
> > > > > > > region, which I see as a single contiguous range of memory and can be
> > > > > > > simplified to have a single reg entry per region.
> > > > > >
> > > > > > My point is rather if multiple reg tuples are found in a reserved memory
> > > > > > node, the kernel must respect them and reserve the memory. I'm not
> > > > > > arguing about whether or not that makes for a good binding.
> > > > >
> > > > > agreed.
> > > >
> > > > My point is why, if the binding defines that just a single tuple should be
> > > > provided.
> > >
> > > FWIW, the usecase I had mentioned in reply to Grant in the patch 5/5
> > > thread [1] could make use of this.  The shared memory region is split
> > > into a main chunk and several "auxiliary" chunk, but collectively these
> > > regions all share the same heap state.
> > >
> > >   Josh
> > >
> > > 1: http://lkml.kernel.org/r/20140205192502.GO20228 at joshc.qualcomm.com
> >
> > The use case seems fine, but I believe it could be properly represented in
> > device tree using multiple single-reg regions as well, unless the consumer
> > can request a block of memory that crosses boundary of two sub-regions
> > specified by reg entries of single region.
> 
> I could probably make a only-one-reg-entry policy work for me, but it
> makes things a bit more awkward.  I'd lose the ability to describe
> "this set of regions need to be logically handled together" directly in
> the reserved memory node, and would need to push it up a layer.
> 
> 	reserved-memory {
> 		smem: smem {
> 			reg = <...>;
> 		};
> 		aux1: auxiliary1 {
> 			reg = <...>;
> 		};
> 		aux2: auxiliary2 {
> 			reg = <...>;
> 		};
> 		...
> 	};

If the regions are used for different purposes, it makes sense I think
to have a separate node for each. Multiple tuples would make more sense
for something like valid DMA regions for a broken device that can only
DMA into a few windows; you could have one tuple per window within a
single node.

It would be possible to collect multiple associated nodes under one
parent node which in turn has reserved-memory for its parent:

	reserved-memory {
		ranges;
		reserved-group {
			ranges;
			smem: smem {
				reg = <...>;
			};
			aux1: auxiliary1 {
				reg = <...>;
			};
			aux2: auxiliary2 {
				reg = <...>;
			};
		};
		...
	};

g.

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

end of thread, other threads:[~2014-02-17 16:53 UTC | newest]

Thread overview: 60+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-04 12:09 [PATCH v2 0/5] reserved-memory regions/CMA in devicetree, again Marek Szyprowski
2014-02-04 12:09 ` Marek Szyprowski
     [not found] ` < 1391515773-6112-5-git-send-email-m.szyprowski@samsung.com>
     [not found] ` < 1391515773-6112-2-git-send-email-m.szyprowski@samsung.com>
2014-02-04 12:09 ` [PATCH v2 1/5] drivers: of: add initialization code for reserved memory Marek Szyprowski
2014-02-04 12:09   ` Marek Szyprowski
     [not found]   ` < 20140205110538.99E47C40A89@trevor.secretlab.ca>
2014-02-05 11:05   ` Grant Likely
2014-02-05 11:05     ` Grant Likely
2014-02-05 11:05     ` Grant Likely
2014-02-11 11:45     ` Marek Szyprowski
2014-02-11 11:45       ` Marek Szyprowski
     [not found]       ` < 20140211121316.24032C40C4D@trevor.secretlab.ca>
2014-02-11 12:13       ` Grant Likely
2014-02-11 12:13         ` Grant Likely
2014-02-11 14:29         ` Tomasz Figa
2014-02-11 14:29           ` Tomasz Figa
2014-02-11 19:01           ` Grant Likely
2014-02-11 19:01             ` Grant Likely
2014-02-11 19:01             ` Grant Likely
2014-02-11 20:02             ` Benjamin Herrenschmidt
2014-02-11 20:02               ` Benjamin Herrenschmidt
2014-02-11 20:04               ` Tomasz Figa
2014-02-11 20:04                 ` Tomasz Figa
2014-02-11 20:19                 ` Josh Cartwright
2014-02-11 20:19                   ` Josh Cartwright
2014-02-11 20:27                   ` Tomasz Figa
2014-02-11 20:27                     ` Tomasz Figa
2014-02-13 19:48                     ` Josh Cartwright
2014-02-13 19:48                       ` Josh Cartwright
2014-02-17 16:53                       ` Grant Likely
2014-02-17 16:53                         ` Grant Likely
2014-02-17 16:47                 ` Grant Likely
2014-02-17 16:47                   ` Grant Likely
2014-02-06 22:08   ` Laura Abbott
2014-02-06 22:08     ` Laura Abbott
2014-02-04 12:09 ` [PATCH v2 2/5] drivers: of: implement reserved-memory handling for dma Marek Szyprowski
2014-02-04 12:09   ` Marek Szyprowski
2014-02-04 12:09   ` Marek Szyprowski
2014-02-04 12:09 ` [PATCH v2 3/5] drivers: of: implement reserved-memory handling for cma Marek Szyprowski
2014-02-04 12:09   ` Marek Szyprowski
2014-02-05 11:09   ` Grant Likely
2014-02-05 11:09     ` Grant Likely
2014-02-05 11:09     ` Grant Likely
2014-02-04 12:09 ` [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree Marek Szyprowski
2014-02-04 12:09   ` Marek Szyprowski
2014-02-05 10:15   ` Grant Likely
2014-02-05 10:15     ` Grant Likely
2014-02-05 10:15     ` Grant Likely
2014-02-06 13:26     ` Marek Szyprowski
2014-02-06 13:26       ` Marek Szyprowski
     [not found]       ` < 20140210215929.4473BC408F7@trevor.secretlab.ca>
2014-02-10 21:59       ` Grant Likely
2014-02-10 21:59         ` Grant Likely
2014-02-11 10:52         ` Marek Szyprowski
2014-02-11 10:52           ` Marek Szyprowski
2014-02-11 11:50           ` Grant Likely
2014-02-11 11:50             ` Grant Likely
2014-02-04 12:09 ` [PATCH v2 5/5] of: document bindings for reserved-memory nodes Marek Szyprowski
2014-02-04 12:09   ` Marek Szyprowski
2014-02-05 10:07   ` Grant Likely
2014-02-05 10:07     ` Grant Likely
2014-02-05 10:07     ` Grant Likely
2014-02-05 19:25     ` Josh Cartwright
2014-02-05 19:25       ` Josh Cartwright

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.