linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] CMA & device tree, another approach
@ 2014-09-11 11:22 Marek Szyprowski
  2014-09-11 11:22 ` [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init Marek Szyprowski
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Marek Szyprowski @ 2014-09-11 11:22 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Michal Nazarewicz, Andrew Morton, Grant Likely, Laura Abbott,
	Josh Cartwright, Joonsoo Kim, Kyungmin Park

Hello,

This is another approach to finish support for reserved memory regions
defined in device tree. Previous attempts 
(http://lists.linaro.org/pipermail/linaro-mm-sig/2014-February/003738.html
and https://lkml.org/lkml/2014/7/14/108) ended in merging parts of the
code and documentation. Merged patches allow to reserve memory, but
there is still no reserved memory drivers nor any code that actually
uses reserved memory regions.

The final conclusion from the above mentioned threads is that there is
no automated reserved memory initialization. All drivers that want to
use reserved memory, should initialize it on their own.

This patch series provides two driver for reserved memory regions (one
based on CMA and one based on dma_coherent allocator). The main
improvement comparing to the previous version is removal of automated
reserved memory for every device and support for named memory regions.

Those patches are for merging, rebased on top of recent linux-next tree.

Best regards
Marek Szyprowski
Samsung R&D Institute Poland

Changes since v1 (https://lkml.org/lkml/2014/8/26/339):
- removed patches for named reserved regions - they will be discussed
  separately
- added a check for 'no-map' property to dma coherent allocator
  (suggested by Laura Abbott)
- removed example code for s5p-mfc driver

Changes since '[PATCH v2 RESEND 0/4] CMA & device tree, once again' version:
(https://lkml.org/lkml/2014/7/14/108)
- added return error value to of_reserved_mem_device_init()
- added support for named memory regions (so more than one region can be
  defined per device)
- added usage example - converted custom reserved memory code used by
  s5p-mfc driver to the generic reserved memory handling code

Patch summary:

Marek Szyprowski (3):
  drivers: of: add return value to of_reserved_mem_device_init
  drivers: dma-coherent: add initialization from device tree
  drivers: dma-contiguous: add initialization from device tree

 drivers/base/dma-coherent.c     | 145 ++++++++++++++++++++++++++++++++++------
 drivers/base/dma-contiguous.c   |  71 ++++++++++++++++++++
 drivers/of/of_reserved_mem.c    |   3 +-
 include/linux/cma.h             |   3 +
 include/linux/of_reserved_mem.h |   9 ++-
 mm/cma.c                        |  62 ++++++++++++++---
 6 files changed, 259 insertions(+), 34 deletions(-)

-- 
1.9.2


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

* [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init
  2014-09-11 11:22 [PATCH v2 0/3] CMA & device tree, another approach Marek Szyprowski
@ 2014-09-11 11:22 ` Marek Szyprowski
  2014-09-26  6:44   ` [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init (fixup) Marek Szyprowski
                     ` (2 more replies)
  2014-09-11 11:22 ` [PATCH v2 2/3] drivers: dma-coherent: add initialization from device tree Marek Szyprowski
                   ` (2 subsequent siblings)
  3 siblings, 3 replies; 14+ messages in thread
From: Marek Szyprowski @ 2014-09-11 11:22 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Michal Nazarewicz, Andrew Morton, Grant Likely, Laura Abbott,
	Josh Cartwright, Joonsoo Kim, Kyungmin Park

Driver calling of_reserved_mem_device_init() might be interested if the
initialization has been successful or not, so add support for returning
error code.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/of/of_reserved_mem.c    | 3 ++-
 include/linux/of_reserved_mem.h | 9 ++++++---
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 59fb12e..7e7de03 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -243,7 +243,7 @@ static inline struct reserved_mem *__find_rmem(struct device_node *node)
  * 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)
+int of_reserved_mem_device_init(struct device *dev)
 {
 	struct reserved_mem *rmem;
 	struct device_node *np;
@@ -260,6 +260,7 @@ void of_reserved_mem_device_init(struct device *dev)
 
 	rmem->ops->device_init(rmem, dev);
 	dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
+	return 0;
 }
 
 /**
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index 5b5efae..ad2f670 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -16,7 +16,7 @@ struct reserved_mem {
 };
 
 struct reserved_mem_ops {
-	void	(*device_init)(struct reserved_mem *rmem,
+	int	(*device_init)(struct reserved_mem *rmem,
 			       struct device *dev);
 	void	(*device_release)(struct reserved_mem *rmem,
 				  struct device *dev);
@@ -28,14 +28,17 @@ typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem);
 	_OF_DECLARE(reservedmem, name, compat, init, reservedmem_of_init_fn)
 
 #ifdef CONFIG_OF_RESERVED_MEM
-void of_reserved_mem_device_init(struct device *dev);
+int of_reserved_mem_device_init(struct device *dev);
 void of_reserved_mem_device_release(struct device *dev);
 
 void fdt_init_reserved_mem(void);
 void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
 			       phys_addr_t base, phys_addr_t size);
 #else
-static inline void of_reserved_mem_device_init(struct device *dev) { }
+static inline int of_reserved_mem_device_init(struct device *dev)
+{
+	return -ENOSYS;
+}
 static inline void of_reserved_mem_device_release(struct device *pdev) { }
 
 static inline void fdt_init_reserved_mem(void) { }
-- 
1.9.2


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

* [PATCH v2 2/3] drivers: dma-coherent: add initialization from device tree
  2014-09-11 11:22 [PATCH v2 0/3] CMA & device tree, another approach Marek Szyprowski
  2014-09-11 11:22 ` [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init Marek Szyprowski
@ 2014-09-11 11:22 ` Marek Szyprowski
  2014-09-24 22:26   ` Andrew Morton
  2014-09-24 22:28   ` Andrew Morton
  2014-09-11 11:22 ` [PATCH v2 3/3] drivers: dma-contiguous: " Marek Szyprowski
  2014-09-23  8:05 ` [PATCH v2 0/3] CMA & device tree, another approach Marek Szyprowski
  3 siblings, 2 replies; 14+ messages in thread
From: Marek Szyprowski @ 2014-09-11 11:22 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Michal Nazarewicz, Andrew Morton, Grant Likely, Laura Abbott,
	Josh Cartwright, Joonsoo Kim, Kyungmin Park

Initialization procedure of dma coherent pool has been split into two
parts, so memory pool can now be initialized without assigning to
particular struct device. Then initialized region can be assigned to
more than one struct device. To protect from concurent allocations from
different devices, a spinlock has been added to dma_coherent_mem
structure. The last part of this patch adds support for handling
'shared-dma-pool' reserved-memory device tree nodes.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/base/dma-coherent.c | 145 ++++++++++++++++++++++++++++++++++++++------
 1 file changed, 126 insertions(+), 19 deletions(-)

diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
index 7d6e84a..8f88c91 100644
--- a/drivers/base/dma-coherent.c
+++ b/drivers/base/dma-coherent.c
@@ -14,11 +14,14 @@ struct dma_coherent_mem {
 	int		size;
 	int		flags;
 	unsigned long	*bitmap;
+	spinlock_t	spinlock;
 };
 
-int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
-				dma_addr_t device_addr, size_t size, int flags)
+static int dma_init_coherent_memory(phys_addr_t phys_addr, dma_addr_t device_addr,
+			     size_t size, int flags,
+			     struct dma_coherent_mem **mem)
 {
+	struct dma_coherent_mem *dma_mem = NULL;
 	void __iomem *mem_base = NULL;
 	int pages = size >> PAGE_SHIFT;
 	int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
@@ -27,27 +30,26 @@ int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
 		goto out;
 	if (!size)
 		goto out;
-	if (dev->dma_mem)
-		goto out;
-
-	/* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
 
 	mem_base = ioremap(phys_addr, size);
 	if (!mem_base)
 		goto out;
 
-	dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
-	if (!dev->dma_mem)
+	dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
+	if (!dma_mem)
 		goto out;
-	dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
-	if (!dev->dma_mem->bitmap)
+	dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+	if (!dma_mem->bitmap)
 		goto free1_out;
 
-	dev->dma_mem->virt_base = mem_base;
-	dev->dma_mem->device_base = device_addr;
-	dev->dma_mem->pfn_base = PFN_DOWN(phys_addr);
-	dev->dma_mem->size = pages;
-	dev->dma_mem->flags = flags;
+	dma_mem->virt_base = mem_base;
+	dma_mem->device_base = device_addr;
+	dma_mem->pfn_base = PFN_DOWN(phys_addr);
+	dma_mem->size = pages;
+	dma_mem->flags = flags;
+	spin_lock_init(&dma_mem->spinlock);
+
+	*mem = dma_mem;
 
 	if (flags & DMA_MEMORY_MAP)
 		return DMA_MEMORY_MAP;
@@ -55,12 +57,51 @@ int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
 	return DMA_MEMORY_IO;
 
  free1_out:
-	kfree(dev->dma_mem);
+	kfree(dma_mem);
  out:
 	if (mem_base)
 		iounmap(mem_base);
 	return 0;
 }
+
+static void dma_release_coherent_memory(struct dma_coherent_mem *mem)
+{
+	if (!mem)
+		return;
+	iounmap(mem->virt_base);
+	kfree(mem->bitmap);
+	kfree(mem);
+}
+
+static int dma_assign_coherent_memory(struct device *dev,
+				      struct dma_coherent_mem *mem)
+{
+	if (dev->dma_mem)
+		return -EBUSY;
+
+	dev->dma_mem = mem;
+	/* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
+
+	return 0;
+}
+
+int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
+				dma_addr_t device_addr, size_t size, int flags)
+{
+	struct dma_coherent_mem *mem;
+	int ret;
+
+	ret = dma_init_coherent_memory(phys_addr, device_addr, size, flags,
+				       &mem);
+	if (ret == 0)
+		return 0;
+
+	if (dma_assign_coherent_memory(dev, mem) == 0)
+		return ret;
+
+	dma_release_coherent_memory(mem);
+	return 0;
+}
 EXPORT_SYMBOL(dma_declare_coherent_memory);
 
 void dma_release_declared_memory(struct device *dev)
@@ -69,10 +110,8 @@ void dma_release_declared_memory(struct device *dev)
 
 	if (!mem)
 		return;
+	dma_release_coherent_memory(mem);
 	dev->dma_mem = NULL;
-	iounmap(mem->virt_base);
-	kfree(mem->bitmap);
-	kfree(mem);
 }
 EXPORT_SYMBOL(dma_release_declared_memory);
 
@@ -80,6 +119,7 @@ void *dma_mark_declared_memory_occupied(struct device *dev,
 					dma_addr_t device_addr, size_t size)
 {
 	struct dma_coherent_mem *mem = dev->dma_mem;
+	unsigned long flags;
 	int pos, err;
 
 	size += device_addr & ~PAGE_MASK;
@@ -87,8 +127,11 @@ void *dma_mark_declared_memory_occupied(struct device *dev,
 	if (!mem)
 		return ERR_PTR(-EINVAL);
 
+	spin_lock_irqsave(&mem->spinlock, flags);
 	pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
 	err = bitmap_allocate_region(mem->bitmap, pos, get_order(size));
+	spin_unlock_irqrestore(&mem->spinlock, flags);
+
 	if (err != 0)
 		return ERR_PTR(err);
 	return mem->virt_base + (pos << PAGE_SHIFT);
@@ -115,6 +158,7 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size,
 {
 	struct dma_coherent_mem *mem;
 	int order = get_order(size);
+	unsigned long flags;
 	int pageno;
 
 	if (!dev)
@@ -124,6 +168,7 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size,
 		return 0;
 
 	*ret = NULL;
+	spin_lock_irqsave(&mem->spinlock, flags);
 
 	if (unlikely(size > (mem->size << PAGE_SHIFT)))
 		goto err;
@@ -138,10 +183,12 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size,
 	*dma_handle = mem->device_base + (pageno << PAGE_SHIFT);
 	*ret = mem->virt_base + (pageno << PAGE_SHIFT);
 	memset(*ret, 0, size);
+	spin_unlock_irqrestore(&mem->spinlock, flags);
 
 	return 1;
 
 err:
+	spin_unlock_irqrestore(&mem->spinlock, flags);
 	/*
 	 * In the case where the allocation can not be satisfied from the
 	 * per-device area, try to fall back to generic memory if the
@@ -171,8 +218,11 @@ int dma_release_from_coherent(struct device *dev, int order, void *vaddr)
 	if (mem && vaddr >= mem->virt_base && vaddr <
 		   (mem->virt_base + (mem->size << PAGE_SHIFT))) {
 		int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
+		unsigned long flags;
 
+		spin_lock_irqsave(&mem->spinlock, flags);
 		bitmap_release_region(mem->bitmap, page, order);
+		spin_unlock_irqrestore(&mem->spinlock, flags);
 		return 1;
 	}
 	return 0;
@@ -218,3 +268,60 @@ int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma,
 	return 0;
 }
 EXPORT_SYMBOL(dma_mmap_from_coherent);
+
+/*
+ * Support for reserved memory regions defined in device tree
+ */
+#ifdef CONFIG_OF_RESERVED_MEM
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_reserved_mem.h>
+
+static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
+{
+	struct dma_coherent_mem *mem = rmem->priv;
+	if (!mem &&
+	    dma_init_coherent_memory(rmem->base, rmem->base, rmem->size,
+				     DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE,
+				     &mem) != DMA_MEMORY_MAP) {
+		pr_info("Reserved memory: failed to init DMA memory pool at %pa, size %ld MiB\n",
+			&rmem->base, (unsigned long)rmem->size / SZ_1M);
+		return -ENODEV;
+	}
+	rmem->priv = mem;
+	dma_assign_coherent_memory(dev, mem);
+	return 0;
+}
+
+static void rmem_dma_device_release(struct reserved_mem *rmem,
+				    struct device *dev)
+{
+	dev->dma_mem = NULL;
+}
+
+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 = rmem->fdt_node;
+
+	if (of_get_flat_dt_prop(node, "reusable", NULL))
+		return -EINVAL;
+
+#ifdef CONFIG_ARM
+	if (!of_get_flat_dt_prop(node, "no-map", NULL)) {
+		pr_info("Reserved memory: regions without no-map are not yet supported\n");
+		return -EINVAL;
+	}
+#endif
+
+	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 0;
+}
+RESERVEDMEM_OF_DECLARE(dma, "shared-dma-pool", rmem_dma_setup);
+#endif
-- 
1.9.2


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

* [PATCH v2 3/3] drivers: dma-contiguous: add initialization from device tree
  2014-09-11 11:22 [PATCH v2 0/3] CMA & device tree, another approach Marek Szyprowski
  2014-09-11 11:22 ` [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init Marek Szyprowski
  2014-09-11 11:22 ` [PATCH v2 2/3] drivers: dma-coherent: add initialization from device tree Marek Szyprowski
@ 2014-09-11 11:22 ` Marek Szyprowski
  2014-09-23  8:05 ` [PATCH v2 0/3] CMA & device tree, another approach Marek Szyprowski
  3 siblings, 0 replies; 14+ messages in thread
From: Marek Szyprowski @ 2014-09-11 11:22 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Michal Nazarewicz, Andrew Morton, Grant Likely, Laura Abbott,
	Josh Cartwright, Joonsoo Kim, Kyungmin Park

Add a function to create CMA region from previously reserved memory
and add support for handling 'shared-dma-pool' reserved-memory device
tree nodes.

Based on previous code provided by Josh Cartwright <joshc@codeaurora.org>

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/base/dma-contiguous.c | 71 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/cma.h           |  3 ++
 mm/cma.c                      | 62 ++++++++++++++++++++++++++++++-------
 3 files changed, 125 insertions(+), 11 deletions(-)

diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 6606abd..eefb81b8 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -211,3 +211,74 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages,
 {
 	return cma_release(dev_get_cma_area(dev), pages, count);
 }
+
+/*
+ * Support for reserved memory regions defined in device tree
+ */
+#ifdef CONFIG_OF_RESERVED_MEM
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_reserved_mem.h>
+
+#undef pr_fmt
+#define pr_fmt(fmt) fmt
+
+static int rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev)
+{
+	struct cma *cma = rmem->priv;
+	if (!cma)
+		return -ENODEV;
+
+	dev_set_cma_area(dev, cma);
+	return 0;
+}
+
+static void rmem_cma_device_release(struct reserved_mem *rmem,
+				    struct device *dev)
+{
+	dev_set_cma_area(dev, NULL);
+}
+
+static const struct reserved_mem_ops rmem_cma_ops = {
+	.device_init	= rmem_cma_device_init,
+	.device_release = rmem_cma_device_release,
+};
+
+static int __init rmem_cma_setup(struct reserved_mem *rmem)
+{
+	phys_addr_t align = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);
+	phys_addr_t mask = align - 1;
+	unsigned long node = rmem->fdt_node;
+	struct cma *cma;
+	int err;
+
+	if (!of_get_flat_dt_prop(node, "reusable", NULL) ||
+	    of_get_flat_dt_prop(node, "no-map", NULL))
+		return -EINVAL;
+
+	if ((rmem->base & mask) || (rmem->size & mask)) {
+		pr_err("Reserved memory: incorrect alignment of CMA region\n");
+		return -EINVAL;
+	}
+
+	err = cma_init_reserved_mem(rmem->base, rmem->size, 0, &cma);
+	if (err) {
+		pr_err("Reserved memory: unable to setup CMA region\n");
+		return err;
+	}
+	/* Architecture specific contiguous memory fixup. */
+	dma_contiguous_early_fixup(rmem->base, rmem->size);
+
+	if (of_get_flat_dt_prop(node, "linux,cma-default", NULL))
+		dma_contiguous_set_default(cma);
+
+	rmem->ops = &rmem_cma_ops;
+	rmem->priv = cma;
+
+	pr_info("Reserved memory: created CMA memory pool at %pa, size %ld MiB\n",
+		&rmem->base, (unsigned long)rmem->size / SZ_1M);
+
+	return 0;
+}
+RESERVEDMEM_OF_DECLARE(cma, "shared-dma-pool", rmem_cma_setup);
+#endif
diff --git a/include/linux/cma.h b/include/linux/cma.h
index 371b930..0430ed0 100644
--- a/include/linux/cma.h
+++ b/include/linux/cma.h
@@ -22,6 +22,9 @@ extern int __init cma_declare_contiguous(phys_addr_t size,
 			phys_addr_t base, phys_addr_t limit,
 			phys_addr_t alignment, unsigned int order_per_bit,
 			bool fixed, struct cma **res_cma);
+extern int cma_init_reserved_mem(phys_addr_t size,
+					phys_addr_t base, int order_per_bit,
+					struct cma **res_cma);
 extern struct page *cma_alloc(struct cma *cma, int count, unsigned int align);
 extern bool cma_release(struct cma *cma, struct page *pages, int count);
 #endif
diff --git a/mm/cma.c b/mm/cma.c
index 474c644..014e145 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -141,6 +141,54 @@ static int __init cma_init_reserved_areas(void)
 core_initcall(cma_init_reserved_areas);
 
 /**
+ * cma_init_reserved_mem() - create custom contiguous area from reserved memory
+ * @base: Base address of the reserved area
+ * @size: Size of the reserved area (in bytes),
+ * @order_per_bit: Order of pages represented by one bit on bitmap.
+ * @res_cma: Pointer to store the created cma region.
+ *
+ * This function creates custom contiguous area from already reserved memory.
+ */
+int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,
+				 int order_per_bit, struct cma **res_cma)
+{
+	struct cma *cma;
+	phys_addr_t alignment;
+
+	/* Sanity checks */
+	if (cma_area_count == ARRAY_SIZE(cma_areas)) {
+		pr_err("Not enough slots for CMA reserved regions!\n");
+		return -ENOSPC;
+	}
+
+	if (!size || !memblock_is_region_reserved(base, size))
+		return -EINVAL;
+
+	/* ensure minimal alignment requied by mm core */
+	alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);
+
+	/* alignment should be aligned with order_per_bit */
+	if (!IS_ALIGNED(alignment >> PAGE_SHIFT, 1 << order_per_bit))
+		return -EINVAL;
+
+	if (ALIGN(base, alignment) != base || ALIGN(size, alignment) != size)
+		return -EINVAL;
+
+	/*
+	 * Each reserved area must be initialised later, when more kernel
+	 * subsystems (like slab allocator) are available.
+	 */
+	cma = &cma_areas[cma_area_count];
+	cma->base_pfn = PFN_DOWN(base);
+	cma->count = size >> PAGE_SHIFT;
+	cma->order_per_bit = order_per_bit;
+	*res_cma = cma;
+	cma_area_count++;
+
+	return 0;
+}
+
+/**
  * cma_declare_contiguous() - reserve custom contiguous area
  * @base: Base address of the reserved area optional, use 0 for any
  * @size: Size of the reserved area (in bytes),
@@ -163,7 +211,6 @@ int __init cma_declare_contiguous(phys_addr_t base,
 			phys_addr_t alignment, unsigned int order_per_bit,
 			bool fixed, struct cma **res_cma)
 {
-	struct cma *cma;
 	phys_addr_t memblock_end = memblock_end_of_DRAM();
 	phys_addr_t highmem_start = __pa(high_memory);
 	int ret = 0;
@@ -235,16 +282,9 @@ int __init cma_declare_contiguous(phys_addr_t base,
 		}
 	}
 
-	/*
-	 * Each reserved area must be initialised later, when more kernel
-	 * subsystems (like slab allocator) are available.
-	 */
-	cma = &cma_areas[cma_area_count];
-	cma->base_pfn = PFN_DOWN(base);
-	cma->count = size >> PAGE_SHIFT;
-	cma->order_per_bit = order_per_bit;
-	*res_cma = cma;
-	cma_area_count++;
+	ret = cma_init_reserved_mem(base, size, order_per_bit, res_cma);
+	if (ret)
+		goto err;
 
 	pr_info("Reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
 		(unsigned long)base);
-- 
1.9.2


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

* Re: [PATCH v2 0/3] CMA & device tree, another approach
  2014-09-11 11:22 [PATCH v2 0/3] CMA & device tree, another approach Marek Szyprowski
                   ` (2 preceding siblings ...)
  2014-09-11 11:22 ` [PATCH v2 3/3] drivers: dma-contiguous: " Marek Szyprowski
@ 2014-09-23  8:05 ` Marek Szyprowski
  3 siblings, 0 replies; 14+ messages in thread
From: Marek Szyprowski @ 2014-09-23  8:05 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, linux-arm-kernel, linaro-mm-sig, Arnd Bergmann,
	Michal Nazarewicz, Grant Likely, Laura Abbott, Josh Cartwright,
	Joonsoo Kim, Kyungmin Park

Hi Andrew,

On 2014-09-11 13:22, Marek Szyprowski wrote:
> Hello,
>
> This is another approach to finish support for reserved memory regions
> defined in device tree. Previous attempts
> (http://lists.linaro.org/pipermail/linaro-mm-sig/2014-February/003738.html
> and https://lkml.org/lkml/2014/7/14/108) ended in merging parts of the
> code and documentation. Merged patches allow to reserve memory, but
> there is still no reserved memory drivers nor any code that actually
> uses reserved memory regions.
>
> The final conclusion from the above mentioned threads is that there is
> no automated reserved memory initialization. All drivers that want to
> use reserved memory, should initialize it on their own.
>
> This patch series provides two driver for reserved memory regions (one
> based on CMA and one based on dma_coherent allocator). The main
> improvement comparing to the previous version is removal of automated
> reserved memory for every device and support for named memory regions.
>
> Those patches are for merging, rebased on top of recent linux-next tree.

Andrew: could you take those patches to your "next" branch together with
other CMA-related changes that are already there?

> Best regards
> Marek Szyprowski
> Samsung R&D Institute Poland
>
> Changes since v1 (https://lkml.org/lkml/2014/8/26/339):
> - removed patches for named reserved regions - they will be discussed
>    separately
> - added a check for 'no-map' property to dma coherent allocator
>    (suggested by Laura Abbott)
> - removed example code for s5p-mfc driver
>
> Changes since '[PATCH v2 RESEND 0/4] CMA & device tree, once again' version:
> (https://lkml.org/lkml/2014/7/14/108)
> - added return error value to of_reserved_mem_device_init()
> - added support for named memory regions (so more than one region can be
>    defined per device)
> - added usage example - converted custom reserved memory code used by
>    s5p-mfc driver to the generic reserved memory handling code
>
> Patch summary:
>
> Marek Szyprowski (3):
>    drivers: of: add return value to of_reserved_mem_device_init
>    drivers: dma-coherent: add initialization from device tree
>    drivers: dma-contiguous: add initialization from device tree
>
>   drivers/base/dma-coherent.c     | 145 ++++++++++++++++++++++++++++++++++------
>   drivers/base/dma-contiguous.c   |  71 ++++++++++++++++++++
>   drivers/of/of_reserved_mem.c    |   3 +-
>   include/linux/cma.h             |   3 +
>   include/linux/of_reserved_mem.h |   9 ++-
>   mm/cma.c                        |  62 ++++++++++++++---
>   6 files changed, 259 insertions(+), 34 deletions(-)
>

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


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

* Re: [PATCH v2 2/3] drivers: dma-coherent: add initialization from device tree
  2014-09-11 11:22 ` [PATCH v2 2/3] drivers: dma-coherent: add initialization from device tree Marek Szyprowski
@ 2014-09-24 22:26   ` Andrew Morton
  2014-09-24 22:28   ` Andrew Morton
  1 sibling, 0 replies; 14+ messages in thread
From: Andrew Morton @ 2014-09-24 22:26 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-kernel, linux-arm-kernel, linaro-mm-sig, Arnd Bergmann,
	Michal Nazarewicz, Grant Likely, Laura Abbott, Josh Cartwright,
	Joonsoo Kim, Kyungmin Park

On Thu, 11 Sep 2014 13:22:40 +0200 Marek Szyprowski <m.szyprowski@samsung.com> wrote:

> Initialization procedure of dma coherent pool has been split into two
> parts, so memory pool can now be initialized without assigning to
> particular struct device. Then initialized region can be assigned to
> more than one struct device. To protect from concurent allocations from
> different devices, a spinlock has been added to dma_coherent_mem
> structure. The last part of this patch adds support for handling
> 'shared-dma-pool' reserved-memory device tree nodes.
> 
> --- a/drivers/base/dma-coherent.c
> +++ b/drivers/base/dma-coherent.c
> @@ -14,11 +14,14 @@ struct dma_coherent_mem {
>  	int		size;
>  	int		flags;
>  	unsigned long	*bitmap;
> +	spinlock_t	spinlock;

A bit of documentation would be nice: explain what the lock protects,
that it is irq-safe, etc.

>  };
>  
> -int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
> -				dma_addr_t device_addr, size_t size, int flags)
> +static int dma_init_coherent_memory(phys_addr_t phys_addr, dma_addr_t device_addr,
> +			     size_t size, int flags,
> +			     struct dma_coherent_mem **mem)
>  {
> +	struct dma_coherent_mem *dma_mem = NULL;

The only reason to initialise this is so we can kfree() it without
checking.  In which case we don't need label free1_out?

--- a/drivers/base/dma-coherent.c~drivers-dma-coherent-add-initialization-from-device-tree-fix
+++ a/drivers/base/dma-coherent.c
@@ -40,7 +40,7 @@ static int dma_init_coherent_memory(phys
 		goto out;
 	dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
 	if (!dma_mem->bitmap)
-		goto free1_out;
+		goto out;
 
 	dma_mem->virt_base = mem_base;
 	dma_mem->device_base = device_addr;
@@ -56,9 +56,8 @@ static int dma_init_coherent_memory(phys
 
 	return DMA_MEMORY_IO;
 
- free1_out:
+out:
 	kfree(dma_mem);
- out:
 	if (mem_base)
 		iounmap(mem_base);
 	return 0;
_


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

* Re: [PATCH v2 2/3] drivers: dma-coherent: add initialization from device tree
  2014-09-11 11:22 ` [PATCH v2 2/3] drivers: dma-coherent: add initialization from device tree Marek Szyprowski
  2014-09-24 22:26   ` Andrew Morton
@ 2014-09-24 22:28   ` Andrew Morton
  1 sibling, 0 replies; 14+ messages in thread
From: Andrew Morton @ 2014-09-24 22:28 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-kernel, linux-arm-kernel, linaro-mm-sig, Arnd Bergmann,
	Michal Nazarewicz, Grant Likely, Laura Abbott, Josh Cartwright,
	Joonsoo Kim, Kyungmin Park

On Thu, 11 Sep 2014 13:22:40 +0200 Marek Szyprowski <m.szyprowski@samsung.com> wrote:

> Initialization procedure of dma coherent pool has been split into two
> parts, so memory pool can now be initialized without assigning to
> particular struct device. Then initialized region can be assigned to
> more than one struct device. To protect from concurent allocations from
> different devices, a spinlock has been added to dma_coherent_mem
> structure. The last part of this patch adds support for handling
> 'shared-dma-pool' reserved-memory device tree nodes.
> 
> ...
>
> +static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
> +{
> +	struct dma_coherent_mem *mem = rmem->priv;
> +	if (!mem &&
> +	    dma_init_coherent_memory(rmem->base, rmem->base, rmem->size,
> +				     DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE,
> +				     &mem) != DMA_MEMORY_MAP) {
> +		pr_info("Reserved memory: failed to init DMA memory pool at %pa, size %ld MiB\n",
> +			&rmem->base, (unsigned long)rmem->size / SZ_1M);

pr_info() seems inappropriate here.  It's an error, so pr_err()?

> +		return -ENODEV;
> +	}
> +	rmem->priv = mem;
> +	dma_assign_coherent_memory(dev, mem);
> +	return 0;
> +}
>
> ...
>
> +static int __init rmem_dma_setup(struct reserved_mem *rmem)
> +{
> +	unsigned long node = rmem->fdt_node;
> +
> +	if (of_get_flat_dt_prop(node, "reusable", NULL))
> +		return -EINVAL;
> +
> +#ifdef CONFIG_ARM
> +	if (!of_get_flat_dt_prop(node, "no-map", NULL)) {
> +		pr_info("Reserved memory: regions without no-map are not yet supported\n");

Same here.

> +		return -EINVAL;
> +	}
> +#endif
> +
> +	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);

This *is* an appropriate use of pr_info().

> +	return 0;
> +}
> +RESERVEDMEM_OF_DECLARE(dma, "shared-dma-pool", rmem_dma_setup);
> +#endif


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

* [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init (fixup)
  2014-09-11 11:22 ` [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init Marek Szyprowski
@ 2014-09-26  6:44   ` Marek Szyprowski
  2014-09-27 13:58     ` Fabio Estevam
  2014-09-26 20:13   ` [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init Arnd Bergmann
  2014-10-09 12:18   ` [PATCH v3] " Marek Szyprowski
  2 siblings, 1 reply; 14+ messages in thread
From: Marek Szyprowski @ 2014-09-26  6:44 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Michal Nazarewicz, Andrew Morton, Grant Likely, Laura Abbott,
	Josh Cartwright, Joonsoo Kim, Kyungmin Park

This patch adds missing return value to error paths.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/of/of_reserved_mem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 7e7de03..e975156 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -250,13 +250,13 @@ int of_reserved_mem_device_init(struct device *dev)
 
 	np = of_parse_phandle(dev->of_node, "memory-region", 0);
 	if (!np)
-		return;
+		return -ENODEV;
 
 	rmem = __find_rmem(np);
 	of_node_put(np);
 
 	if (!rmem || !rmem->ops || !rmem->ops->device_init)
-		return;
+		return -ENIVAL;
 
 	rmem->ops->device_init(rmem, dev);
 	dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
-- 
1.9.2


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

* Re: [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init
  2014-09-11 11:22 ` [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init Marek Szyprowski
  2014-09-26  6:44   ` [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init (fixup) Marek Szyprowski
@ 2014-09-26 20:13   ` Arnd Bergmann
  2014-10-09 12:18   ` [PATCH v3] " Marek Szyprowski
  2 siblings, 0 replies; 14+ messages in thread
From: Arnd Bergmann @ 2014-09-26 20:13 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Marek Szyprowski, linux-kernel, Laura Abbott, Josh Cartwright,
	Michal Nazarewicz, linaro-mm-sig, Kyungmin Park, Grant Likely,
	Andrew Morton, Joonsoo Kim

On Thursday 11 September 2014, Marek Szyprowski wrote:
> -void of_reserved_mem_device_init(struct device *dev)
> +int of_reserved_mem_device_init(struct device *dev)
>  {
>         struct reserved_mem *rmem;
>         struct device_node *np;
> @@ -260,6 +260,7 @@ void of_reserved_mem_device_init(struct device *dev)
>  
>         rmem->ops->device_init(rmem, dev);
>         dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
> +       return 0;
>  }

This function has two other 'return' statements that now are missing 
a return value for the error case and cause undefined behavior
in the caller.

	Arnd

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

* Re: [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init (fixup)
  2014-09-26  6:44   ` [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init (fixup) Marek Szyprowski
@ 2014-09-27 13:58     ` Fabio Estevam
  0 siblings, 0 replies; 14+ messages in thread
From: Fabio Estevam @ 2014-09-27 13:58 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-kernel, linux-arm-kernel, Laura Abbott, Arnd Bergmann,
	Josh Cartwright, Michal Nazarewicz, linaro-mm-sig, Kyungmin Park,
	Grant Likely, Andrew Morton, Joonsoo Kim

Hi Marek,

On Fri, Sep 26, 2014 at 3:44 AM, Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
> This patch adds missing return value to error paths.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

I have also sent a similar fix:
http://www.spinics.net/lists/devicetree/msg51127.html

> ---
>  drivers/of/of_reserved_mem.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> index 7e7de03..e975156 100644
> --- a/drivers/of/of_reserved_mem.c
> +++ b/drivers/of/of_reserved_mem.c
> @@ -250,13 +250,13 @@ int of_reserved_mem_device_init(struct device *dev)
>
>         np = of_parse_phandle(dev->of_node, "memory-region", 0);
>         if (!np)
> -               return;
> +               return -ENODEV;
>
>         rmem = __find_rmem(np);
>         of_node_put(np);
>
>         if (!rmem || !rmem->ops || !rmem->ops->device_init)
> -               return;
> +               return -ENIVAL;

ENIVAL does not exist. I guess you meant EINVAL ;-)

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

* [PATCH v3] drivers: of: add return value to of_reserved_mem_device_init
  2014-09-11 11:22 ` [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init Marek Szyprowski
  2014-09-26  6:44   ` [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init (fixup) Marek Szyprowski
  2014-09-26 20:13   ` [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init Arnd Bergmann
@ 2014-10-09 12:18   ` Marek Szyprowski
  2014-10-13 11:19     ` Arnd Bergmann
  2 siblings, 1 reply; 14+ messages in thread
From: Marek Szyprowski @ 2014-10-09 12:18 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Michal Nazarewicz, Andrew Morton, Grant Likely, Laura Abbott,
	Josh Cartwright, Joonsoo Kim, Kyungmin Park

Driver calling of_reserved_mem_device_init() might be interested if the
initialization has been successful or not, so add support for returning
error code.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/of/of_reserved_mem.c    | 7 ++++---
 include/linux/of_reserved_mem.h | 9 ++++++---
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 59fb12e..70780ad 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -243,23 +243,24 @@ static inline struct reserved_mem *__find_rmem(struct device_node *node)
  * 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)
+int of_reserved_mem_device_init(struct device *dev)
 {
 	struct reserved_mem *rmem;
 	struct device_node *np;
 
 	np = of_parse_phandle(dev->of_node, "memory-region", 0);
 	if (!np)
-		return;
+		return -ENODEV;
 
 	rmem = __find_rmem(np);
 	of_node_put(np);
 
 	if (!rmem || !rmem->ops || !rmem->ops->device_init)
-		return;
+		return -EINVAL;
 
 	rmem->ops->device_init(rmem, dev);
 	dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
+	return 0;
 }
 
 /**
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index 5b5efae..ad2f670 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -16,7 +16,7 @@ struct reserved_mem {
 };
 
 struct reserved_mem_ops {
-	void	(*device_init)(struct reserved_mem *rmem,
+	int	(*device_init)(struct reserved_mem *rmem,
 			       struct device *dev);
 	void	(*device_release)(struct reserved_mem *rmem,
 				  struct device *dev);
@@ -28,14 +28,17 @@ typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem);
 	_OF_DECLARE(reservedmem, name, compat, init, reservedmem_of_init_fn)
 
 #ifdef CONFIG_OF_RESERVED_MEM
-void of_reserved_mem_device_init(struct device *dev);
+int of_reserved_mem_device_init(struct device *dev);
 void of_reserved_mem_device_release(struct device *dev);
 
 void fdt_init_reserved_mem(void);
 void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
 			       phys_addr_t base, phys_addr_t size);
 #else
-static inline void of_reserved_mem_device_init(struct device *dev) { }
+static inline int of_reserved_mem_device_init(struct device *dev)
+{
+	return -ENOSYS;
+}
 static inline void of_reserved_mem_device_release(struct device *pdev) { }
 
 static inline void fdt_init_reserved_mem(void) { }
-- 
1.9.2


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

* Re: [PATCH v3] drivers: of: add return value to of_reserved_mem_device_init
  2014-10-09 12:18   ` [PATCH v3] " Marek Szyprowski
@ 2014-10-13 11:19     ` Arnd Bergmann
  2014-10-15 11:01       ` [PATCH v4] " Marek Szyprowski
  0 siblings, 1 reply; 14+ messages in thread
From: Arnd Bergmann @ 2014-10-13 11:19 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-kernel, linux-arm-kernel, linaro-mm-sig, Michal Nazarewicz,
	Andrew Morton, Grant Likely, Laura Abbott, Josh Cartwright,
	Joonsoo Kim, Kyungmin Park, rmk+kernel

On Thursday 09 October 2014 14:18:00 Marek Szyprowski wrote:
> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> index 59fb12e..70780ad 100644
> --- a/drivers/of/of_reserved_mem.c
> +++ b/drivers/of/of_reserved_mem.c

>         if (!rmem || !rmem->ops || !rmem->ops->device_init)
> -               return;
> +               return -EINVAL;
>  
>         rmem->ops->device_init(rmem, dev);
>         dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
> +       return 0;
>  }

You don't actually return the value from ->device_init() here but always
return 0 on success. There are no callers of this function, so it's
hard to tell if this actually makes a difference, but it contradicts
your patch description.

> diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
> index 5b5efae..ad2f670 100644
> --- a/include/linux/of_reserved_mem.h
> +++ b/include/linux/of_reserved_mem.h
> @@ -16,7 +16,7 @@ struct reserved_mem {
>  };
>  
>  struct reserved_mem_ops {
> -       void    (*device_init)(struct reserved_mem *rmem,
> +       int     (*device_init)(struct reserved_mem *rmem,
>                                struct device *dev);
>         void    (*device_release)(struct reserved_mem *rmem,
>                                   struct device *dev);

This part is definitely needed to avoid the new compile warnings we
are getting.

	Arnd

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

* [PATCH v4] drivers: of: add return value to of_reserved_mem_device_init
  2014-10-13 11:19     ` Arnd Bergmann
@ 2014-10-15 11:01       ` Marek Szyprowski
  2014-10-20 19:04         ` [Linaro-mm-sig] " Arnd Bergmann
  0 siblings, 1 reply; 14+ messages in thread
From: Marek Szyprowski @ 2014-10-15 11:01 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel
  Cc: Marek Szyprowski, linaro-mm-sig, Arnd Bergmann,
	Michal Nazarewicz, Andrew Morton, Grant Likely, Laura Abbott,
	Josh Cartwright, Joonsoo Kim, Kyungmin Park, Russell King,
	Stephen Rothwell

Driver calling of_reserved_mem_device_init() might be interested if the
initialization has been successful or not, so add support for returning
error code.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
This patch fixes build warining caused by commit
7bfa5ab6fa1b18f53fb94f922e107e6fbdc5e485 ("drivers: dma-coherent: add
initialization from device tree"), which has been merged without this
change and without fixing function return value.
---
 drivers/base/dma-contiguous.c   |  3 ++-
 drivers/of/of_reserved_mem.c    | 14 +++++++++-----
 include/linux/of_reserved_mem.h |  9 ++++++---
 3 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 473ff4892401..950fff9ce453 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -223,9 +223,10 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages,
 #undef pr_fmt
 #define pr_fmt(fmt) fmt
 
-static void rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev)
+static int rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev)
 {
 	dev_set_cma_area(dev, rmem->priv);
+	return 0;
 }
 
 static void rmem_cma_device_release(struct reserved_mem *rmem,
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 59fb12e84e6b..dc566b38645f 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -243,23 +243,27 @@ static inline struct reserved_mem *__find_rmem(struct device_node *node)
  * 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)
+int of_reserved_mem_device_init(struct device *dev)
 {
 	struct reserved_mem *rmem;
 	struct device_node *np;
+	int ret;
 
 	np = of_parse_phandle(dev->of_node, "memory-region", 0);
 	if (!np)
-		return;
+		return -ENODEV;
 
 	rmem = __find_rmem(np);
 	of_node_put(np);
 
 	if (!rmem || !rmem->ops || !rmem->ops->device_init)
-		return;
+		return -EINVAL;
+
+	ret = rmem->ops->device_init(rmem, dev);
+	if (ret == 0)
+		dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
 
-	rmem->ops->device_init(rmem, dev);
-	dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
+	return ret;
 }
 
 /**
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index 5b5efae09135..ad2f67054372 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -16,7 +16,7 @@ struct reserved_mem {
 };
 
 struct reserved_mem_ops {
-	void	(*device_init)(struct reserved_mem *rmem,
+	int	(*device_init)(struct reserved_mem *rmem,
 			       struct device *dev);
 	void	(*device_release)(struct reserved_mem *rmem,
 				  struct device *dev);
@@ -28,14 +28,17 @@ typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem);
 	_OF_DECLARE(reservedmem, name, compat, init, reservedmem_of_init_fn)
 
 #ifdef CONFIG_OF_RESERVED_MEM
-void of_reserved_mem_device_init(struct device *dev);
+int of_reserved_mem_device_init(struct device *dev);
 void of_reserved_mem_device_release(struct device *dev);
 
 void fdt_init_reserved_mem(void);
 void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
 			       phys_addr_t base, phys_addr_t size);
 #else
-static inline void of_reserved_mem_device_init(struct device *dev) { }
+static inline int of_reserved_mem_device_init(struct device *dev)
+{
+	return -ENOSYS;
+}
 static inline void of_reserved_mem_device_release(struct device *pdev) { }
 
 static inline void fdt_init_reserved_mem(void) { }
-- 
1.9.2


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

* Re: [Linaro-mm-sig] [PATCH v4] drivers: of: add return value to of_reserved_mem_device_init
  2014-10-15 11:01       ` [PATCH v4] " Marek Szyprowski
@ 2014-10-20 19:04         ` Arnd Bergmann
  0 siblings, 0 replies; 14+ messages in thread
From: Arnd Bergmann @ 2014-10-20 19:04 UTC (permalink / raw)
  To: linaro-mm-sig
  Cc: Marek Szyprowski, linux-kernel, linux-arm-kernel,
	Stephen Rothwell, Josh Cartwright, Michal Nazarewicz,
	Kyungmin Park, Grant Likely, Russell King, Andrew Morton,
	Joonsoo Kim

On Wednesday 15 October 2014 13:01:42 Marek Szyprowski wrote:
> Driver calling of_reserved_mem_device_init() might be interested if the
> initialization has been successful or not, so add support for returning
> error code.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
> This patch fixes build warining caused by commit
> 7bfa5ab6fa1b18f53fb94f922e107e6fbdc5e485 ("drivers: dma-coherent: add
> initialization from device tree"), which has been merged without this
> change and without fixing function return value.
> 

Acked-by: Arnd Bergmann <arnd@arndb.de>

It also makes sense to encode the information you have below the ---
line as

Fixes: 7bfa5ab6fa1b1 ("drivers: dma-coherent: add initialization from device tree")

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

end of thread, other threads:[~2014-10-20 19:05 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-11 11:22 [PATCH v2 0/3] CMA & device tree, another approach Marek Szyprowski
2014-09-11 11:22 ` [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init Marek Szyprowski
2014-09-26  6:44   ` [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init (fixup) Marek Szyprowski
2014-09-27 13:58     ` Fabio Estevam
2014-09-26 20:13   ` [PATCH v2 1/3] drivers: of: add return value to of_reserved_mem_device_init Arnd Bergmann
2014-10-09 12:18   ` [PATCH v3] " Marek Szyprowski
2014-10-13 11:19     ` Arnd Bergmann
2014-10-15 11:01       ` [PATCH v4] " Marek Szyprowski
2014-10-20 19:04         ` [Linaro-mm-sig] " Arnd Bergmann
2014-09-11 11:22 ` [PATCH v2 2/3] drivers: dma-coherent: add initialization from device tree Marek Szyprowski
2014-09-24 22:26   ` Andrew Morton
2014-09-24 22:28   ` Andrew Morton
2014-09-11 11:22 ` [PATCH v2 3/3] drivers: dma-contiguous: " Marek Szyprowski
2014-09-23  8:05 ` [PATCH v2 0/3] CMA & device tree, another approach Marek Szyprowski

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