Re: [PATCH v3 3/7] of: reserved_mem: add support for named reserved mem nodes

2016-01-04 Thread Marek Szyprowski

Hi Rob,

On 2015-12-31 00:25, Rob Herring wrote:

On Wed, Dec 16, 2015 at 9:37 AM, Marek Szyprowski
<m.szyprow...@samsung.com> wrote:

This patch allows device drivers to initialize more than one reserved
memory region assigned to given device. When driver needs to use more
than one reserved memory region, it should allocate child devices and
initialize regions by index or name for each of its child devices.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
  .../bindings/reserved-memory/reserved-memory.txt   |   2 +
  .../devicetree/bindings/resource-names.txt |   1 +
  drivers/of/of_reserved_mem.c   | 104 +
  include/linux/of_reserved_mem.h|  31 +-
  4 files changed, 115 insertions(+), 23 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt 
b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
index 3da0ebdba8d9..43a14957fd64 100644
--- a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
+++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
@@ -74,6 +74,8 @@ 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
+memory-region-names (optional) - supplemental names property, provide array of
+names to identify memory regions

  Example
  ---
diff --git a/Documentation/devicetree/bindings/resource-names.txt 
b/Documentation/devicetree/bindings/resource-names.txt
index e280fef6f265..51823e99b983 100644
--- a/Documentation/devicetree/bindings/resource-names.txt
+++ b/Documentation/devicetree/bindings/resource-names.txt
@@ -12,6 +12,7 @@ Resource Property Supplemental Names Property
  regreg-names
  clocks clock-names
  interrupts interrupt-names
+memory-region  memory-region-names

The other cases of *-names should correspond to actual h/w names for a
h/w block. memory-regions are not really h/w. So I'd prefer to not add
memory-region-names. If you want a name for the region, put it in the
region node. The name for each client node is not going to be
different.


There is a difference between a name in the region node and a name assigned
in client node. Reserved memory region bindings already allows assigning
given region to more than one device. In such case the name put in the
region itself is not really useful.

In my case (Exynos MFC device) the names are related to HW names. The memory
regions are named in the hw documentation (referred as 'left memory bank'
and 'right memory bank'). Using those names in the binding is also simply
convenient (no need to remember which regions is at which index number).

Those names might be also convenient for describing Android's ION related
regions, although I didn't look deep into details of such use case.

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

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


[PATCH v3 5/7] media: set proper max seg size for devices on Exynos SoCs

2015-12-16 Thread Marek Szyprowski
All multimedia devices found on Exynos SoCs support only contiguous
buffers, so set DMA max segment size to DMA_BIT_MASK(32) to let memory
allocator to correctly create contiguous memory mappings.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 drivers/media/platform/exynos-gsc/gsc-core.c  | 1 +
 drivers/media/platform/exynos4-is/fimc-core.c | 1 +
 drivers/media/platform/exynos4-is/fimc-is.c   | 1 +
 drivers/media/platform/exynos4-is/fimc-lite.c | 1 +
 drivers/media/platform/s5p-g2d/g2d.c  | 1 +
 drivers/media/platform/s5p-jpeg/jpeg-core.c   | 1 +
 drivers/media/platform/s5p-mfc/s5p_mfc.c  | 2 ++
 drivers/media/platform/s5p-tv/mixer_video.c   | 1 +
 8 files changed, 9 insertions(+)

diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c 
b/drivers/media/platform/exynos-gsc/gsc-core.c
index 9b9e423e4fc4..4f90be43b5a9 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.c
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -1140,6 +1140,7 @@ static int gsc_probe(struct platform_device *pdev)
goto err_m2m;
 
/* Initialize continious memory allocator */
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
gsc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(gsc->alloc_ctx)) {
ret = PTR_ERR(gsc->alloc_ctx);
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c 
b/drivers/media/platform/exynos4-is/fimc-core.c
index cef2a7f07cdb..368e19b50498 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/exynos4-is/fimc-core.c
@@ -1019,6 +1019,7 @@ static int fimc_probe(struct platform_device *pdev)
}
 
/* Initialize contiguous memory allocator */
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(fimc->alloc_ctx)) {
ret = PTR_ERR(fimc->alloc_ctx);
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c 
b/drivers/media/platform/exynos4-is/fimc-is.c
index 49658ca39e51..123772fa0241 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -841,6 +841,7 @@ static int fimc_is_probe(struct platform_device *pdev)
if (ret < 0)
goto err_pm;
 
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
is->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(is->alloc_ctx)) {
ret = PTR_ERR(is->alloc_ctx);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c 
b/drivers/media/platform/exynos4-is/fimc-lite.c
index 6f76afd909c4..9cfd2221f53d 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1564,6 +1564,7 @@ static int fimc_lite_probe(struct platform_device *pdev)
goto err_sd;
}
 
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(fimc->alloc_ctx)) {
ret = PTR_ERR(fimc->alloc_ctx);
diff --git a/drivers/media/platform/s5p-g2d/g2d.c 
b/drivers/media/platform/s5p-g2d/g2d.c
index e1936d9d27da..31f6c233b146 100644
--- a/drivers/media/platform/s5p-g2d/g2d.c
+++ b/drivers/media/platform/s5p-g2d/g2d.c
@@ -681,6 +681,7 @@ static int g2d_probe(struct platform_device *pdev)
goto put_clk_gate;
}
 
+   vb2_dma_contig_set_max_seg_size(>dev, DMA_BIT_MASK(32));
dev->alloc_ctx = vb2_dma_contig_init_ctx(>dev);
if (IS_ERR(dev->alloc_ctx)) {
ret = PTR_ERR(dev->alloc_ctx);
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 4a608cbe0fdb..6bd92f014a23 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2839,6 +2839,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
goto device_register_rollback;
}
 
+   vb2_dma_contig_set_max_seg_size(>dev, DMA_BIT_MASK(32));
jpeg->alloc_ctx = vb2_dma_contig_init_ctx(>dev);
if (IS_ERR(jpeg->alloc_ctx)) {
v4l2_err(>v4l2_dev, "Failed to init memory allocator\n");
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 3ffe2ecfd5ef..3e9cdafe2168 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1143,11 +1143,13 @@ static int s5p_mfc_probe(struct platform_device *pdev)
}
}
 
+   vb2_dma_contig_set_max_seg_size(dev->mem_dev_l, DMA_BIT_MASK(32));
dev->alloc_ctx[0] = vb2_dma_contig_init_ctx(dev->mem_dev_l);
if (IS_ERR(dev->alloc_ctx[0])) {
ret = PTR_ERR(dev->alloc_ctx[0]);
goto err_res;
}
+   vb2_dma_contig_set_max

[PATCH v3 0/7] Exynos: MFC driver: reserved memory cleanup and IOMMU support

2015-12-16 Thread Marek Szyprowski
Hello,

This patchset finally perform cleanup of custom code in s5p-mfc codec
driver. The first part is removal of custom, driver specific code for
intializing and handling of reserved memory. Instead, a generic code for
reserved memory regions is used. Then, once it is done, the proper setup
of DMA parameters (max segment size) is applied for all multimedia
devices found on Exynos SoCs to let them properly handle shared buffers
mapped into contiguous DMA address space. The last patch adds support
for IOMMU to MFC driver. Some additional code is needed because of
specific requirements of MFC device firmware (see patch 7 for more
details). When no IOMMU is available, the code fallbacks to generic
reserved memory regions.

After applying this patchset, MFC device works correctly when IOMMU is
either enabled or disabled.

Patches have been tested on top of linux-next from 20151207. I would
prefer to merge patches 1-2 via Samsung tree and patches 3-7 via media
tree (there are no compile-time dependencies between patches 1-2 and
3-7). Patches have been tested on Odroid U3 (Exynos 4412 based) and
Odroid XU3 (Exynos 5422 based) boards.

Best regards
Marek Szyprowski
Samsung R Institute Poland


Changelog:
v3:
- fixed issues pointed by Laurent Pinchart:
  - added documentation to memory-region-names property,
  - changed devm_kzalloc to kzalloc in vb2_dma_contig_set_max_seg_size() to
avoid access to freed memory after reloading driver module
- unified odroid mfc reserved memory configuration with other Exynos4 boards

v2: http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/97025
- reworked of_reserved_mem_init* functions on request from Rob Herring,
  added separate index and name based selection of reserved region
- adapted for of_reserved_mem_init* related changes

v1: https://www.mail-archive.com/linux-media@vger.kernel.org/msg94100.html
- initial version of another approach for this problem, rewrote driver code
  for new reserved memory bindings, which finally have been merged some
  time ago

v0: 
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-August/189259.html
- old patchset solving the same problem, abandoned due to other tasks
  and long time of merging reserved memory bindings and support code for
  it

Patch summary:

Marek Szyprowski (7):
  ARM: Exynos: convert MFC device to generic reserved memory bindings
  ARM: dts: exynos4412-odroid*: enable MFC device
  of: reserved_mem: add support for named reserved mem nodes
  media: vb2-dma-contig: add helper for setting dma max seg size
  media: set proper max seg size for devices on Exynos SoCs
  media: s5p-mfc: replace custom reserved memory init code with generic
one
  media: s5p-mfc: add iommu support

 .../devicetree/bindings/media/s5p-mfc.txt  |  16 +--
 .../bindings/reserved-memory/reserved-memory.txt   |   2 +
 .../devicetree/bindings/resource-names.txt |   1 +
 arch/arm/boot/dts/exynos4210-origen.dts|  22 ++-
 arch/arm/boot/dts/exynos4210-smdkv310.dts  |  22 ++-
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi|  24 
 arch/arm/boot/dts/exynos4412-origen.dts|  22 ++-
 arch/arm/boot/dts/exynos4412-smdk4412.dts  |  22 ++-
 arch/arm/boot/dts/exynos5250-arndale.dts   |  22 ++-
 arch/arm/boot/dts/exynos5250-smdk5250.dts  |  22 ++-
 arch/arm/boot/dts/exynos5250-spring.dts|  22 ++-
 arch/arm/boot/dts/exynos5420-arndale-octa.dts  |  22 ++-
 arch/arm/boot/dts/exynos5420-smdk5420.dts  |  22 ++-
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |  22 ++-
 arch/arm/mach-exynos/Makefile  |   2 -
 arch/arm/mach-exynos/exynos.c  |  19 ---
 arch/arm/mach-exynos/mfc.h |  16 ---
 arch/arm/mach-exynos/s5p-dev-mfc.c |  94 -
 drivers/media/platform/exynos-gsc/gsc-core.c   |   1 +
 drivers/media/platform/exynos4-is/fimc-core.c  |   1 +
 drivers/media/platform/exynos4-is/fimc-is.c|   1 +
 drivers/media/platform/exynos4-is/fimc-lite.c  |   1 +
 drivers/media/platform/s5p-g2d/g2d.c   |   1 +
 drivers/media/platform/s5p-jpeg/jpeg-core.c|   1 +
 drivers/media/platform/s5p-mfc/s5p_mfc.c   | 153 -
 drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h |  79 +++
 drivers/media/platform/s5p-tv/mixer_video.c|   1 +
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  14 ++
 drivers/of/of_reserved_mem.c   | 104 +++---
 include/linux/of_reserved_mem.h|  31 -
 include/media/videobuf2-dma-contig.h   |   1 +
 31 files changed, 535 insertions(+), 248 deletions(-)
 delete mode 100644 arch/arm/mach-exynos/mfc.h
 delete mode 100644 arch/arm/mach-exynos/s5p-dev-mfc.c
 create mode 100644 drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h

-- 
1.9.2

--
To unsubscribe from this list: send the line "unsubscribe devic

[PATCH v3 4/7] media: vb2-dma-contig: add helper for setting dma max seg size

2015-12-16 Thread Marek Szyprowski
Add a helper function for device drivers to set DMA's max_seg_size.
Setting it to largest possible value lets DMA-mapping API always create
contiguous mappings in DMA address space. This is essential for all
devices, which use dma-contig videobuf2 memory allocator and shared
buffers.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 14 ++
 include/media/videobuf2-dma-contig.h   |  1 +
 2 files changed, 15 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index c33127284cfe..bd893788d1ae 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -742,6 +742,20 @@ void vb2_dma_contig_cleanup_ctx(void *alloc_ctx)
 }
 EXPORT_SYMBOL_GPL(vb2_dma_contig_cleanup_ctx);
 
+int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size)
+{
+   if (!dev->dma_parms) {
+   dev->dma_parms = kzalloc(sizeof(dev->dma_parms), GFP_KERNEL);
+   if (!dev->dma_parms)
+   return -ENOMEM;
+   }
+   if (dma_get_max_seg_size(dev) < size)
+   return dma_set_max_seg_size(dev, size);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_dma_contig_set_max_seg_size);
+
 MODULE_DESCRIPTION("DMA-contig memory handling routines for videobuf2");
 MODULE_AUTHOR("Pawel Osciak <pa...@osciak.com>");
 MODULE_LICENSE("GPL");
diff --git a/include/media/videobuf2-dma-contig.h 
b/include/media/videobuf2-dma-contig.h
index c33dfa69d7ab..0e6ba644939e 100644
--- a/include/media/videobuf2-dma-contig.h
+++ b/include/media/videobuf2-dma-contig.h
@@ -26,6 +26,7 @@ vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned 
int plane_no)
 
 void *vb2_dma_contig_init_ctx(struct device *dev);
 void vb2_dma_contig_cleanup_ctx(void *alloc_ctx);
+int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size);
 
 extern const struct vb2_mem_ops vb2_dma_contig_memops;
 
-- 
1.9.2

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


[PATCH v3 6/7] media: s5p-mfc: replace custom reserved memory init code with generic one

2015-12-16 Thread Marek Szyprowski
This patch removes custom code for initialization and handling of
reserved memory regions in s5p-mfc driver and replaces it with generic
named reserved memory regions specified in device tree.

s5p-mfc driver now handles two reserved memory regions: "left" and
"right", defined by generic reserved memory bindings. Support for non-dt
platform has been removed, because all supported platforms have been
converted to device tree.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 drivers/media/platform/s5p-mfc/s5p_mfc.c | 129 +++
 1 file changed, 62 insertions(+), 67 deletions(-)

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 3e9cdafe2168..306344994c8e 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "s5p_mfc_common.h"
 #include "s5p_mfc_ctrl.h"
@@ -1022,55 +1023,67 @@ static const struct v4l2_file_operations s5p_mfc_fops = 
{
.mmap = s5p_mfc_mmap,
 };
 
-static int match_child(struct device *dev, void *data)
+/* DMA memory related helper functions */
+static void s5p_mfc_memdev_release(struct device *dev)
 {
-   if (!dev_name(dev))
-   return 0;
-   return !strcmp(dev_name(dev), (char *)data);
+   of_reserved_mem_device_release(dev);
 }
 
-static void *mfc_get_drv_data(struct platform_device *pdev);
-
-static int s5p_mfc_alloc_memdevs(struct s5p_mfc_dev *dev)
+static struct device *s5p_mfc_alloc_memdev(struct device *dev, const char 
*name)
 {
-   unsigned int mem_info[2] = { };
+   struct device *child;
+   int ret;
 
-   dev->mem_dev_l = devm_kzalloc(>plat_dev->dev,
-   sizeof(struct device), GFP_KERNEL);
-   if (!dev->mem_dev_l) {
-   mfc_err("Not enough memory\n");
-   return -ENOMEM;
-   }
-   device_initialize(dev->mem_dev_l);
-   of_property_read_u32_array(dev->plat_dev->dev.of_node,
-   "samsung,mfc-l", mem_info, 2);
-   if (dma_declare_coherent_memory(dev->mem_dev_l, mem_info[0],
-   mem_info[0], mem_info[1],
-   DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) {
-   mfc_err("Failed to declare coherent memory for\n"
-   "MFC device\n");
-   return -ENOMEM;
+   child = devm_kzalloc(dev, sizeof(struct device), GFP_KERNEL);
+   if (!child)
+   return NULL;
+
+   device_initialize(child);
+   dev_set_name(child, "%s:%s", dev_name(dev), name);
+   child->parent = dev;
+   child->bus = dev->bus;
+   child->coherent_dma_mask = dev->coherent_dma_mask;
+   child->dma_mask = dev->dma_mask;
+   child->release = s5p_mfc_memdev_release;
+
+   if (device_add(child) == 0) {
+   ret = of_reserved_mem_init_by_name(child, dev->of_node, name);
+   if (ret == 0)
+   return child;
}
 
-   dev->mem_dev_r = devm_kzalloc(>plat_dev->dev,
-   sizeof(struct device), GFP_KERNEL);
-   if (!dev->mem_dev_r) {
-   mfc_err("Not enough memory\n");
-   return -ENOMEM;
-   }
-   device_initialize(dev->mem_dev_r);
-   of_property_read_u32_array(dev->plat_dev->dev.of_node,
-   "samsung,mfc-r", mem_info, 2);
-   if (dma_declare_coherent_memory(dev->mem_dev_r, mem_info[0],
-   mem_info[0], mem_info[1],
-   DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) {
-   pr_err("Failed to declare coherent memory for\n"
-   "MFC device\n");
-   return -ENOMEM;
+   put_device(child);
+   return NULL;
+}
+
+static int s5p_mfc_configure_dma_memory(struct s5p_mfc_dev *mfc_dev)
+{
+   struct device *dev = _dev->plat_dev->dev;
+
+   /*
+* Create and initialize virtual devices for accessing
+* reserved memory regions.
+*/
+   mfc_dev->mem_dev_l = s5p_mfc_alloc_memdev(dev, "left");
+   if (!mfc_dev->mem_dev_l)
+   return -ENODEV;
+   mfc_dev->mem_dev_r = s5p_mfc_alloc_memdev(dev, "right");
+   if (!mfc_dev->mem_dev_r) {
+   device_unregister(mfc_dev->mem_dev_l);
+   return -ENODEV;
}
+
return 0;
 }
 
+static void s5p_mfc_unconfigure_dma_memory(struct s5p_mfc_dev *mfc_dev)
+{
+   device_unregister(mfc_dev->mem_dev_l);
+   device_unregister(mfc_dev->mem_dev_r);
+}
+
+static void *mfc_get_drv_data(struct platform_device *pdev);
+
 /* MFC probe function */
 static int s5p_m

[PATCH v3 3/7] of: reserved_mem: add support for named reserved mem nodes

2015-12-16 Thread Marek Szyprowski
This patch allows device drivers to initialize more than one reserved
memory region assigned to given device. When driver needs to use more
than one reserved memory region, it should allocate child devices and
initialize regions by index or name for each of its child devices.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 .../bindings/reserved-memory/reserved-memory.txt   |   2 +
 .../devicetree/bindings/resource-names.txt |   1 +
 drivers/of/of_reserved_mem.c   | 104 +
 include/linux/of_reserved_mem.h|  31 +-
 4 files changed, 115 insertions(+), 23 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt 
b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
index 3da0ebdba8d9..43a14957fd64 100644
--- a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
+++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
@@ -74,6 +74,8 @@ 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
+memory-region-names (optional) - supplemental names property, provide array of
+names to identify memory regions
 
 Example
 ---
diff --git a/Documentation/devicetree/bindings/resource-names.txt 
b/Documentation/devicetree/bindings/resource-names.txt
index e280fef6f265..51823e99b983 100644
--- a/Documentation/devicetree/bindings/resource-names.txt
+++ b/Documentation/devicetree/bindings/resource-names.txt
@@ -12,6 +12,7 @@ Resource Property Supplemental Names Property
 regreg-names
 clocks clock-names
 interrupts interrupt-names
+memory-region  memory-region-names
 
 Usage:
 
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 1a3556a9e9ea..c58b362aaa63 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MAX_RESERVED_REGIONS   16
 static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
@@ -287,53 +288,116 @@ static inline struct reserved_mem *__find_rmem(struct 
device_node *node)
return NULL;
 }
 
+struct rmem_assigned_device {
+   struct device *dev;
+   struct reserved_mem *rmem;
+   struct list_head list;
+};
+
+static LIST_HEAD(of_rmem_assigned_device_list);
+static DEFINE_MUTEX(of_rmem_assigned_device_mutex);
+
 /**
  * of_reserved_mem_device_init() - assign reserved memory region to given 
device
+ * @dev:   Pointer to the device to configure
+ * @np:Pointer to the device_node with 'reserved-memory' 
property
+ * @idx:   Index of selected region
+ *
+ * This function assigns respective DMA-mapping operations based on reserved
+ * memory region specified by 'memory-region' property in @np node to the @dev
+ * device. When driver needs to use more than one reserved memory region, it
+ * should allocate child devices and initialize regions by name for each of
+ * child device.
  *
- * This function assign memory region pointed by "memory-region" device tree
- * property to the given device.
+ * Returns error code or zero on success.
  */
-int of_reserved_mem_device_init(struct device *dev)
+int of_reserved_mem_init(struct device *dev, struct device_node *np, int idx)
 {
+   struct rmem_assigned_device *rd;
+   struct device_node *target;
struct reserved_mem *rmem;
-   struct device_node *np;
int ret;
 
-   np = of_parse_phandle(dev->of_node, "memory-region", 0);
-   if (!np)
-   return -ENODEV;
+   if (!np || !dev)
+   return -EINVAL;
+
+   target = of_parse_phandle(np, "memory-region", idx);
+   if (!target)
+   return -EINVAL;
 
-   rmem = __find_rmem(np);
-   of_node_put(np);
+   rmem = __find_rmem(target);
+   of_node_put(target);
 
if (!rmem || !rmem->ops || !rmem->ops->device_init)
return -EINVAL;
 
+   rd = kmalloc(sizeof(struct rmem_assigned_device), GFP_KERNEL);
+   if (!rd)
+   return -ENOMEM;
+
ret = rmem->ops->device_init(rmem, dev);
-   if (ret == 0)
+   if (ret == 0) {
+   rd->dev = dev;
+   rd->rmem = rmem;
+
+   mutex_lock(_rmem_assigned_device_mutex);
+   list_add(>list, _rmem_assigned_device_list);
+   mutex_unlock(_rmem_assigned_device_mutex);
+
dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
+   } else {
+   kfree(rd);
+   }
 
return ret;
 }
-EXPORT_SYMBOL_GPL(of_reserved_mem_device_init);
+EXPORT_SYMBOL_GPL(of_reserved_mem_init);
+
+/*

[PATCH v3 7/7] media: s5p-mfc: add iommu support

2015-12-16 Thread Marek Szyprowski
This patch adds support for IOMMU to s5p-mfc device driver. MFC firmware
is limited and it cannot use the default configuration. If IOMMU is
available, the patch disables the default DMA address space
configuration and creates a new address space of size limited to 256M
and base address set to 0x2000.

For now the same address space is shared by both 'left' and 'right'
memory channels, because the DMA/IOMMU frameworks do not support
configuring them separately. This is not optimal, but besides limiting
total address space available has no other drawbacks (MFC firmware
supports 256M of address space per each channel).

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 drivers/media/platform/s5p-mfc/s5p_mfc.c   | 24 
 drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h | 79 ++
 2 files changed, 103 insertions(+)
 create mode 100644 drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 306344994c8e..bae7c0f7bfd4 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -30,6 +30,7 @@
 #include "s5p_mfc_dec.h"
 #include "s5p_mfc_enc.h"
 #include "s5p_mfc_intr.h"
+#include "s5p_mfc_iommu.h"
 #include "s5p_mfc_opr.h"
 #include "s5p_mfc_cmd.h"
 #include "s5p_mfc_pm.h"
@@ -1061,6 +1062,22 @@ static int s5p_mfc_configure_dma_memory(struct 
s5p_mfc_dev *mfc_dev)
struct device *dev = _dev->plat_dev->dev;
 
/*
+* When IOMMU is available, we cannot use the default configuration,
+* because of MFC firmware requirements: address space limited to
+* 256M and non-zero default start address.
+* This is still simplified, not optimal configuration, but for now
+* IOMMU core doesn't allow to configure device's IOMMUs channel
+* separately.
+*/
+   if (exynos_is_iommu_available(dev)) {
+   int ret = exynos_configure_iommu(dev, S5P_MFC_IOMMU_DMA_BASE,
+S5P_MFC_IOMMU_DMA_SIZE);
+   if (ret == 0)
+   mfc_dev->mem_dev_l = mfc_dev->mem_dev_r = dev;
+   return ret;
+   }
+
+   /*
 * Create and initialize virtual devices for accessing
 * reserved memory regions.
 */
@@ -1078,6 +1095,13 @@ static int s5p_mfc_configure_dma_memory(struct 
s5p_mfc_dev *mfc_dev)
 
 static void s5p_mfc_unconfigure_dma_memory(struct s5p_mfc_dev *mfc_dev)
 {
+   struct device *dev = _dev->plat_dev->dev;
+
+   if (exynos_is_iommu_available(dev)) {
+   exynos_unconfigure_iommu(dev);
+   return;
+   }
+
device_unregister(mfc_dev->mem_dev_l);
device_unregister(mfc_dev->mem_dev_r);
 }
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h 
b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
new file mode 100644
index ..5d1d1c2922e8
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics Co.Ltd
+ * Authors: Marek Szyprowski <m.szyprow...@samsung.com>
+ *
+ * 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
+ * option) any later version.
+ */
+
+#ifndef S5P_MFC_IOMMU_H_
+#define S5P_MFC_IOMMU_H_
+
+#define S5P_MFC_IOMMU_DMA_BASE 0x2000lu
+#define S5P_MFC_IOMMU_DMA_SIZE SZ_256M
+
+#ifdef CONFIG_EXYNOS_IOMMU
+
+#include 
+
+static inline bool exynos_is_iommu_available(struct device *dev)
+{
+   return dev->archdata.iommu != NULL;
+}
+
+static inline void exynos_unconfigure_iommu(struct device *dev)
+{
+   struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+
+   arm_iommu_detach_device(dev);
+   arm_iommu_release_mapping(mapping);
+}
+
+static inline int exynos_configure_iommu(struct device *dev,
+unsigned int base, unsigned int size)
+{
+   struct dma_iommu_mapping *mapping = NULL;
+   int ret;
+
+   /* Disable the default mapping created by device core */
+   if (to_dma_iommu_mapping(dev))
+   exynos_unconfigure_iommu(dev);
+
+   mapping = arm_iommu_create_mapping(dev->bus, base, size);
+   if (IS_ERR(mapping)) {
+   pr_warn("Failed to create IOMMU mapping for device %s\n",
+   dev_name(dev));
+   return PTR_ERR(mapping);
+   }
+
+   ret = arm_iommu_attach_device(dev, mapping);
+   if (ret) {
+   pr_warn("Failed to attached device %s to IOMMU_mapping\n",
+   dev_name(dev));
+   arm_iommu_release_mapping(mapping);

[PATCH v3 2/7] ARM: dts: exynos4412-odroid*: enable MFC device

2015-12-16 Thread Marek Szyprowski
Enable support for Multimedia Codec (MFC) device for all Exynos4412-based
Odroid boards.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 24 
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi 
b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index 395c3ca9601e..349e6cc51283 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -18,6 +18,24 @@
stdout-path = _1;
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   mfc_left: region@5100 {
+   compatible = "shared-dma-pool";
+   no-map;
+   reg = <0x5100 0x80>;
+   };
+
+   mfc_right: region@4300 {
+   compatible = "shared-dma-pool";
+   no-map;
+   reg = <0x4300 0x80>;
+   };
+   };
+
firmware@0204F000 {
compatible = "samsung,secure-firmware";
reg = <0x0204F000 0x1000>;
@@ -447,6 +465,12 @@
clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
 };
 
+ {
+   memory-region = <_left>, <_right>;
+   memory-region-names = "left", "right";
+   status = "okay";
+};
+
  {
status = "okay";
 };
-- 
1.9.2

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


[PATCH v3 1/7] ARM: Exynos: convert MFC device to generic reserved memory bindings

2015-12-16 Thread Marek Szyprowski
This patch replaces custom properties for definining reserved memory
regions with generic reserved memory bindings. All custom code for
handling MFC-specific reserved memory can be now removed from Exynos-DT
generic board code.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 .../devicetree/bindings/media/s5p-mfc.txt  | 16 ++--
 arch/arm/boot/dts/exynos4210-origen.dts| 22 -
 arch/arm/boot/dts/exynos4210-smdkv310.dts  | 22 -
 arch/arm/boot/dts/exynos4412-origen.dts| 22 -
 arch/arm/boot/dts/exynos4412-smdk4412.dts  | 22 -
 arch/arm/boot/dts/exynos5250-arndale.dts   | 22 -
 arch/arm/boot/dts/exynos5250-smdk5250.dts  | 22 -
 arch/arm/boot/dts/exynos5250-spring.dts| 22 -
 arch/arm/boot/dts/exynos5420-arndale-octa.dts  | 22 -
 arch/arm/boot/dts/exynos5420-smdk5420.dts  | 22 -
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi | 22 -
 arch/arm/mach-exynos/Makefile  |  2 -
 arch/arm/mach-exynos/exynos.c  | 19 -
 arch/arm/mach-exynos/mfc.h | 16 
 arch/arm/mach-exynos/s5p-dev-mfc.c | 94 --
 15 files changed, 208 insertions(+), 159 deletions(-)
 delete mode 100644 arch/arm/mach-exynos/mfc.h
 delete mode 100644 arch/arm/mach-exynos/s5p-dev-mfc.c

diff --git a/Documentation/devicetree/bindings/media/s5p-mfc.txt 
b/Documentation/devicetree/bindings/media/s5p-mfc.txt
index 2d5787eac91a..4603673c593b 100644
--- a/Documentation/devicetree/bindings/media/s5p-mfc.txt
+++ b/Documentation/devicetree/bindings/media/s5p-mfc.txt
@@ -21,16 +21,16 @@ Required properties:
   - clock-names : from common clock binding: must contain "mfc",
  corresponding to entry in the clocks property.
 
-  - samsung,mfc-r : Base address of the first memory bank used by MFC
-   for DMA contiguous memory allocation and its size.
-
-  - samsung,mfc-l : Base address of the second memory bank used by MFC
-   for DMA contiguous memory allocation and its size.
-
 Optional properties:
   - power-domains : power-domain property defined with a phandle
   to respective power domain.
 
+  - memory-region : from reserved memory binding: phandles to two reserved
+   memory regions: accessed by "left" and "right" mfc memory bus
+   interfaces, used when no SYSMMU support is available
+  - memory-region-names : from reserved memory binding: must be "left"
+   and "right"
+
 Example:
 SoC specific DT entry:
 
@@ -46,6 +46,6 @@ mfc: codec@1340 {
 Board specific DT entry:
 
 codec@1340 {
-   samsung,mfc-r = <0x4300 0x80>;
-   samsung,mfc-l = <0x5100 0x80>;
+   memory-region = <_left>, <_right>;
+   memory-region-names = "left", "right";
 };
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts 
b/arch/arm/boot/dts/exynos4210-origen.dts
index 5821ad87e32c..4b7637dfa392 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -30,6 +30,24 @@
   0x7000 0x1000>;
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   mfc_left: region@5100 {
+   compatible = "shared-dma-pool";
+   no-map;
+   reg = <0x5100 0x80>;
+   };
+
+   mfc_right: region@4300 {
+   compatible = "shared-dma-pool";
+   no-map;
+   reg = <0x4300 0x80>;
+   };
+   };
+
chosen {
bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x4100,8M 
console=ttySAC2,115200 init=/linuxrc";
stdout-path = _2;
@@ -288,8 +306,8 @@
 };
 
  {
-   samsung,mfc-r = <0x4300 0x80>;
-   samsung,mfc-l = <0x5100 0x80>;
+   memory-region = <_left>, <_right>;
+   memory-region-names = "left", "right";
status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts 
b/arch/arm/boot/dts/exynos4210-smdkv310.dts
index 104cbb33d2bb..efafc5721817 100644
--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -26,6 +26,24 @@
reg = <0x4000 0x8000>;
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   mfc_left: region@5100 {
+   compatible = "shared-dma-pool";
+   no-map;
+

Re: [PATCH v2 4/7] media: vb2-dma-contig: add helper for setting dma max seg size

2015-12-15 Thread Marek Szyprowski

Hi Laurent,

On 2015-12-14 16:50, Laurent Pinchart wrote:

Hi Marek,

On Monday 14 December 2015 10:20:22 Marek Szyprowski wrote:

On 2015-12-13 20:57, Laurent Pinchart wrote:

On Wednesday 09 December 2015 14:58:19 Marek Szyprowski wrote:

Add a helper function for device drivers to set DMA's max_seg_size.
Setting it to largest possible value lets DMA-mapping API always create
contiguous mappings in DMA address space. This is essential for all
devices, which use dma-contig videobuf2 memory allocator and shared
buffers.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

   drivers/media/v4l2-core/videobuf2-dma-contig.c | 15 +++
   include/media/videobuf2-dma-contig.h   |  1 +
   2 files changed, 16 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c
b/drivers/media/v4l2-core/videobuf2-dma-contig.c index c331272..628518d
100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -742,6 +742,21 @@ void vb2_dma_contig_cleanup_ctx(void *alloc_ctx)

   }
   EXPORT_SYMBOL_GPL(vb2_dma_contig_cleanup_ctx);

+int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int
size)
+{
+   if (!dev->dma_parms) {

When can this function be called with dev->dma_parms not NULL ?

When one loads a module with multimedia driver (which calls this
function), then unloads and loads it again. It is rather safe to have this
check.

Don't you have a much bigger problem in that case ? When you unload the module
the device will be unbound from the driver, causing the memory allocated by
devm_kzalloc to be freed. dev->dma_parms will then point to freed memory,
which will get reused by all subsequent calls to dma_get_max_seg_size(),
dma_get_max_seg_size() & co (including the ones in this function).


You are right. I've thought that devm resources are freed on device 
release not
driver remove. Then probably the safest fix is to change devm_kzalloc 
back to

kzalloc.


+   dev->dma_parms = devm_kzalloc(dev, sizeof(dev->dma_parms),
+ GFP_KERNEL);
+   if (!dev->dma_parms)
+   return -ENOMEM;
+   }
+   if (dma_get_max_seg_size(dev) < size)
+   return dma_set_max_seg_size(dev, size);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_dma_contig_set_max_seg_size);
+
   MODULE_DESCRIPTION("DMA-contig memory handling routines for
   videobuf2");
   MODULE_AUTHOR("Pawel Osciak <pa...@osciak.com>");
   MODULE_LICENSE("GPL");
diff --git a/include/media/videobuf2-dma-contig.h
b/include/media/videobuf2-dma-contig.h index c33dfa6..0e6ba64 100644
--- a/include/media/videobuf2-dma-contig.h
+++ b/include/media/videobuf2-dma-contig.h
@@ -26,6 +26,7 @@ vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb,
unsigned int plane_no)
  void *vb2_dma_contig_init_ctx(struct device *dev);
  void vb2_dma_contig_cleanup_ctx(void *alloc_ctx);
+int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int
size);
  extern const struct vb2_mem_ops vb2_dma_contig_memops;


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

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


Re: [PATCH v2 0/7] Exynos: MFC driver: reserved memory cleanup and IOMMU support

2015-12-14 Thread Marek Szyprowski

Hello,

On 2015-12-13 20:52, Laurent Pinchart wrote:

Hi Marek,

Thank you for the patches.

On Wednesday 09 December 2015 14:58:15 Marek Szyprowski wrote:

Hello,

This patchset finally perform cleanup of custom code in s5p-mfc codec
driver. The first part is removal of custom, driver specific code for
intializing and handling of reserved memory. Instead, a generic code for
reserved memory regions is used.

Should you update the reserved memory bindings documentation
(Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt) to
document usage of the memory-region-names property ?


Okay, I will update documentation as well.


Then, once it is done, the proper setup
of DMA parameters (max segment size) is applied for all multimedia
devices found on Exynos SoCs to let them properly handle shared buffers
mapped into contiguous DMA address space. The last patch adds support
for IOMMU to MFC driver. Some additional code is needed because of
specific requirements of MFC device firmware (see patch 7 for more
details). When no IOMMU is available, the code fallbacks to generic
reserved memory regions.

After applying this patchset, MFC device works correctly when IOMMU is
either enabled or disabled.

Patches have been tested on top of linux-next from 20151207. I would
prefer to merge patches 1-2 via Samsung tree and patches 3-7 via media
tree (there are no compile-time dependencies between patches 1-2 and
3-7). Patches have been tested on Odroid U3 (Exynos 4412 based) and
Odroid XU3 (Exynos 5422 based) boards.

Best regards
Marek Szyprowski
Samsung R Institute Poland


Changelog:
v2:
- reworked of_reserved_mem_init* functions on request from Rob Herring,
   added separate index and name based selection of reserved region
- adapted for of_reserved_mem_init* related changes

v1: https://www.mail-archive.com/linux-media@vger.kernel.org/msg94100.html
- initial version of another approach for this problem, rewrote driver code
   for new reserved memory bindings, which finally have been merged some
   time ago

v0:
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-August/189259.ht
ml - old patchset solving the same problem, abandoned due to other tasks and
long time of merging reserved memory bindings and support code for it

Patch summary:

Marek Szyprowski (7):
   ARM: Exynos: convert MFC device to generic reserved memory bindings
   ARM: dts: exynos4412-odroid*: enable MFC device
   of: reserved_mem: add support for named reserved mem nodes
   media: vb2-dma-contig: add helper for setting dma max seg size
   media: set proper max seg size for devices on Exynos SoCs
   media: s5p-mfc: replace custom reserved memory init code with generic
 one
   media: s5p-mfc: add iommu support

  .../devicetree/bindings/media/s5p-mfc.txt  |  16 +--
  arch/arm/boot/dts/exynos4210-origen.dts|  22 ++-
  arch/arm/boot/dts/exynos4210-smdkv310.dts  |  22 ++-
  arch/arm/boot/dts/exynos4412-odroid-common.dtsi|  24 
  arch/arm/boot/dts/exynos4412-origen.dts|  22 ++-
  arch/arm/boot/dts/exynos4412-smdk4412.dts  |  22 ++-
  arch/arm/boot/dts/exynos5250-arndale.dts   |  22 ++-
  arch/arm/boot/dts/exynos5250-smdk5250.dts  |  22 ++-
  arch/arm/boot/dts/exynos5250-spring.dts|  22 ++-
  arch/arm/boot/dts/exynos5420-arndale-octa.dts  |  22 ++-
  arch/arm/boot/dts/exynos5420-smdk5420.dts  |  22 ++-
  arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |  22 ++-
  arch/arm/mach-exynos/Makefile  |   2 -
  arch/arm/mach-exynos/exynos.c  |  19 ---
  arch/arm/mach-exynos/mfc.h |  16 ---
  arch/arm/mach-exynos/s5p-dev-mfc.c |  94 -
  drivers/media/platform/exynos-gsc/gsc-core.c   |   1 +
  drivers/media/platform/exynos4-is/fimc-core.c  |   1 +
  drivers/media/platform/exynos4-is/fimc-is.c|   1 +
  drivers/media/platform/exynos4-is/fimc-lite.c  |   1 +
  drivers/media/platform/s5p-g2d/g2d.c   |   1 +
  drivers/media/platform/s5p-jpeg/jpeg-core.c|   1 +
  drivers/media/platform/s5p-mfc/s5p_mfc.c   | 153 ++
  drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h |  79 +++
  drivers/media/platform/s5p-tv/mixer_video.c|   1 +
  drivers/media/v4l2-core/videobuf2-dma-contig.c |  15 ++
  drivers/of/of_reserved_mem.c   | 104 +++---
  include/linux/of_reserved_mem.h|  31 -
  include/media/videobuf2-dma-contig.h   |   1 +
  29 files changed, 533 insertions(+), 248 deletions(-)
  delete mode 100644 arch/arm/mach-exynos/mfc.h
  delete mode 100644 arch/arm/mach-exynos/s5p-dev-mfc.c
  create mode 100644 drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h


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

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of

Re: [PATCH v2 4/7] media: vb2-dma-contig: add helper for setting dma max seg size

2015-12-14 Thread Marek Szyprowski

Hello,

On 2015-12-13 20:57, Laurent Pinchart wrote:

Hi Marek,

Thank you for the patch.

On Wednesday 09 December 2015 14:58:19 Marek Szyprowski wrote:

Add a helper function for device drivers to set DMA's max_seg_size.
Setting it to largest possible value lets DMA-mapping API always create
contiguous mappings in DMA address space. This is essential for all
devices, which use dma-contig videobuf2 memory allocator and shared
buffers.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
  drivers/media/v4l2-core/videobuf2-dma-contig.c | 15 +++
  include/media/videobuf2-dma-contig.h   |  1 +
  2 files changed, 16 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c
b/drivers/media/v4l2-core/videobuf2-dma-contig.c index c331272..628518d
100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -742,6 +742,21 @@ void vb2_dma_contig_cleanup_ctx(void *alloc_ctx)
  }
  EXPORT_SYMBOL_GPL(vb2_dma_contig_cleanup_ctx);

+int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size)
+{
+   if (!dev->dma_parms) {

When can this function be called with dev->dma_parms not NULL ?


When one loads a module with multimedia driver (which calls this 
function), then

unloads and loads it again. It is rather safe to have this check.


+   dev->dma_parms = devm_kzalloc(dev, sizeof(dev->dma_parms),
+ GFP_KERNEL);
+   if (!dev->dma_parms)
+   return -ENOMEM;
+   }
+   if (dma_get_max_seg_size(dev) < size)
+   return dma_set_max_seg_size(dev, size);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_dma_contig_set_max_seg_size);
+
  MODULE_DESCRIPTION("DMA-contig memory handling routines for videobuf2");
  MODULE_AUTHOR("Pawel Osciak <pa...@osciak.com>");
  MODULE_LICENSE("GPL");
diff --git a/include/media/videobuf2-dma-contig.h
b/include/media/videobuf2-dma-contig.h index c33dfa6..0e6ba64 100644
--- a/include/media/videobuf2-dma-contig.h
+++ b/include/media/videobuf2-dma-contig.h
@@ -26,6 +26,7 @@ vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb,
unsigned int plane_no)

  void *vb2_dma_contig_init_ctx(struct device *dev);
  void vb2_dma_contig_cleanup_ctx(void *alloc_ctx);
+int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size);

  extern const struct vb2_mem_ops vb2_dma_contig_memops;


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

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


Re: [PATCH 3/7] of: reserved_mem: add support for named reserved mem nodes

2015-12-09 Thread Marek Szyprowski

Hello,

On 2015-12-08 15:58, Rob Herring wrote:

On Mon, Dec 7, 2015 at 6:08 AM, Marek Szyprowski
<m.szyprow...@samsung.com> wrote:

This patch allows device drivers to use more than one reserved memory
region assigned to given device. When NULL name is passed to
of_reserved_mem_device_init(), the default (first) region is used.

Every property that's an array does not need a name property. Just use
indexes please.


Okay, I will update the patch and add support for indices in the main
implementation as well as a wrapper, which accepts "name" parameter.




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

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 1a3556a9e9ea..0a0b23b73004 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -21,6 +21,7 @@
  #include 
  #include 
  #include 
+#include 

  #define MAX_RESERVED_REGIONS   16
  static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
@@ -287,31 +288,84 @@ static inline struct reserved_mem *__find_rmem(struct 
device_node *node)
 return NULL;
  }

+static struct reserved_mem *__node_to_rmem(struct device_node *node,
+  const char *name)
+{
+   struct reserved_mem *rmem;
+   struct device_node *target;
+   int idx = 0;
+
+   if (!node)
+   return NULL;
+
+   if (name) {
+   idx = of_property_match_string(node,
+  "memory-region-names", name);
+   if (idx < 0)
+   return NULL;
+   }
+
+   target = of_parse_phandle(node, "memory-region", idx);
+   if (!target)
+   return NULL;
+   rmem = __find_rmem(target);
+   of_node_put(target);
+
+   return rmem;
+}
+
+struct rmem_assigned_device {
+   struct device *dev;
+   struct reserved_mem *rmem;
+   struct list_head list;
+};
+
+static LIST_HEAD(of_rmem_assigned_device_list);
+static DEFINE_MUTEX(of_rmem_assigned_device_mutex);

Not that this is a fast or contended path, but I think a spinlock
would be more appropriate here.


This is not meant to be called really often and for all kinds on 
initialization lists
and structures I saw that mutexes are used instead of spinlocks. There 
is no intention

to let this function to be called from atomic context.




+
  /**
   * of_reserved_mem_device_init() - assign reserved memory region to given 
device
+ * @dev:   Pointer to the device to configure
+ * @np:Pointer to the device_node with 'reserved-memory' 
property
+ * @name:  Optional name of the selected region (can be NULL)
+ *
+ * This function assigns respective DMA-mapping operations based on reserved
+ * memory regionspecified by 'memory-region' property in @np node, named @name
+ * to the @dev device. When NULL name is provided, the default (first) memory
+ * region is used. When driver needs to use more than one reserved memory
+ * region, it should allocate child devices and initialize regions by name for
+ * each of child device.
   *
- * This function assign memory region pointed by "memory-region" device tree
- * property to the given device.
+ * Returns error code or zero on success.
   */
-int of_reserved_mem_device_init(struct device *dev)
+int of_reserved_mem_device_init(struct device *dev, struct device_node *np,
+   const char *name)
  {
+   struct rmem_assigned_device *rd;
 struct reserved_mem *rmem;
-   struct device_node *np;
 int ret;

-   np = of_parse_phandle(dev->of_node, "memory-region", 0);
-   if (!np)
-   return -ENODEV;
-
-   rmem = __find_rmem(np);
-   of_node_put(np);
-
+   rmem = __node_to_rmem(np, name);
 if (!rmem || !rmem->ops || !rmem->ops->device_init)
 return -EINVAL;

+   rd = kmalloc(sizeof(struct rmem_assigned_device), GFP_KERNEL);
+   if (!rd)
+   return -ENOMEM;
+
 ret = rmem->ops->device_init(rmem, dev);
-   if (ret == 0)
+   if (ret == 0) {
+   rd->dev = dev;
+   rd->rmem = rmem;
+
+   mutex_lock(_rmem_assigned_device_mutex);
+   list_add(>list, _rmem_assigned_device_list);
+   mutex_unlock(_rmem_assigned_device_mutex);
+
 dev_info(dev, "assigned reserved memory node %s\n", 
rmem->name);
+   } else {
+   kfree(rd);
+   }

 return ret;
  }
@@ -319,21 +373,26 @@ EXPORT_SYMBOL_GPL(of_reserved_mem_device_init);

  /**
   * of_reserved_mem_device_release() - release reserved memory device 
structures
+ * @dev:   Pointer to t

[PATCH v2 0/7] Exynos: MFC driver: reserved memory cleanup and IOMMU support

2015-12-09 Thread Marek Szyprowski
Hello,

This patchset finally perform cleanup of custom code in s5p-mfc codec
driver. The first part is removal of custom, driver specific code for
intializing and handling of reserved memory. Instead, a generic code for
reserved memory regions is used. Then, once it is done, the proper setup
of DMA parameters (max segment size) is applied for all multimedia
devices found on Exynos SoCs to let them properly handle shared buffers
mapped into contiguous DMA address space. The last patch adds support
for IOMMU to MFC driver. Some additional code is needed because of
specific requirements of MFC device firmware (see patch 7 for more
details). When no IOMMU is available, the code fallbacks to generic
reserved memory regions.

After applying this patchset, MFC device works correctly when IOMMU is
either enabled or disabled.

Patches have been tested on top of linux-next from 20151207. I would
prefer to merge patches 1-2 via Samsung tree and patches 3-7 via media
tree (there are no compile-time dependencies between patches 1-2 and
3-7). Patches have been tested on Odroid U3 (Exynos 4412 based) and
Odroid XU3 (Exynos 5422 based) boards.

Best regards
Marek Szyprowski
Samsung R Institute Poland


Changelog:
v2:
- reworked of_reserved_mem_init* functions on request from Rob Herring,
  added separate index and name based selection of reserved region
- adapted for of_reserved_mem_init* related changes

v1: https://www.mail-archive.com/linux-media@vger.kernel.org/msg94100.html
- initial version of another approach for this problem, rewrote driver code
  for new reserved memory bindings, which finally have been merged some
  time ago

v0: 
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-August/189259.html
- old patchset solving the same problem, abandoned due to other tasks
  and long time of merging reserved memory bindings and support code for
  it

Patch summary:

Marek Szyprowski (7):
  ARM: Exynos: convert MFC device to generic reserved memory bindings
  ARM: dts: exynos4412-odroid*: enable MFC device
  of: reserved_mem: add support for named reserved mem nodes
  media: vb2-dma-contig: add helper for setting dma max seg size
  media: set proper max seg size for devices on Exynos SoCs
  media: s5p-mfc: replace custom reserved memory init code with generic
one
  media: s5p-mfc: add iommu support

 .../devicetree/bindings/media/s5p-mfc.txt  |  16 +--
 arch/arm/boot/dts/exynos4210-origen.dts|  22 ++-
 arch/arm/boot/dts/exynos4210-smdkv310.dts  |  22 ++-
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi|  24 
 arch/arm/boot/dts/exynos4412-origen.dts|  22 ++-
 arch/arm/boot/dts/exynos4412-smdk4412.dts  |  22 ++-
 arch/arm/boot/dts/exynos5250-arndale.dts   |  22 ++-
 arch/arm/boot/dts/exynos5250-smdk5250.dts  |  22 ++-
 arch/arm/boot/dts/exynos5250-spring.dts|  22 ++-
 arch/arm/boot/dts/exynos5420-arndale-octa.dts  |  22 ++-
 arch/arm/boot/dts/exynos5420-smdk5420.dts  |  22 ++-
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |  22 ++-
 arch/arm/mach-exynos/Makefile  |   2 -
 arch/arm/mach-exynos/exynos.c  |  19 ---
 arch/arm/mach-exynos/mfc.h |  16 ---
 arch/arm/mach-exynos/s5p-dev-mfc.c |  94 -
 drivers/media/platform/exynos-gsc/gsc-core.c   |   1 +
 drivers/media/platform/exynos4-is/fimc-core.c  |   1 +
 drivers/media/platform/exynos4-is/fimc-is.c|   1 +
 drivers/media/platform/exynos4-is/fimc-lite.c  |   1 +
 drivers/media/platform/s5p-g2d/g2d.c   |   1 +
 drivers/media/platform/s5p-jpeg/jpeg-core.c|   1 +
 drivers/media/platform/s5p-mfc/s5p_mfc.c   | 153 -
 drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h |  79 +++
 drivers/media/platform/s5p-tv/mixer_video.c|   1 +
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  15 ++
 drivers/of/of_reserved_mem.c   | 104 +++---
 include/linux/of_reserved_mem.h|  31 -
 include/media/videobuf2-dma-contig.h   |   1 +
 29 files changed, 533 insertions(+), 248 deletions(-)
 delete mode 100644 arch/arm/mach-exynos/mfc.h
 delete mode 100644 arch/arm/mach-exynos/s5p-dev-mfc.c
 create mode 100644 drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h

-- 
1.9.2

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


[PATCH v2 1/7] ARM: Exynos: convert MFC device to generic reserved memory bindings

2015-12-09 Thread Marek Szyprowski
This patch replaces custom properties for definining reserved memory
regions with generic reserved memory bindings. All custom code for
handling MFC-specific reserved memory can be now removed from Exynos-DT
generic board code.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 .../devicetree/bindings/media/s5p-mfc.txt  | 16 ++--
 arch/arm/boot/dts/exynos4210-origen.dts| 22 -
 arch/arm/boot/dts/exynos4210-smdkv310.dts  | 22 -
 arch/arm/boot/dts/exynos4412-origen.dts| 22 -
 arch/arm/boot/dts/exynos4412-smdk4412.dts  | 22 -
 arch/arm/boot/dts/exynos5250-arndale.dts   | 22 -
 arch/arm/boot/dts/exynos5250-smdk5250.dts  | 22 -
 arch/arm/boot/dts/exynos5250-spring.dts| 22 -
 arch/arm/boot/dts/exynos5420-arndale-octa.dts  | 22 -
 arch/arm/boot/dts/exynos5420-smdk5420.dts  | 22 -
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi | 22 -
 arch/arm/mach-exynos/Makefile  |  2 -
 arch/arm/mach-exynos/exynos.c  | 19 -
 arch/arm/mach-exynos/mfc.h | 16 
 arch/arm/mach-exynos/s5p-dev-mfc.c | 94 --
 15 files changed, 208 insertions(+), 159 deletions(-)
 delete mode 100644 arch/arm/mach-exynos/mfc.h
 delete mode 100644 arch/arm/mach-exynos/s5p-dev-mfc.c

diff --git a/Documentation/devicetree/bindings/media/s5p-mfc.txt 
b/Documentation/devicetree/bindings/media/s5p-mfc.txt
index 2d5787e..4603673 100644
--- a/Documentation/devicetree/bindings/media/s5p-mfc.txt
+++ b/Documentation/devicetree/bindings/media/s5p-mfc.txt
@@ -21,16 +21,16 @@ Required properties:
   - clock-names : from common clock binding: must contain "mfc",
  corresponding to entry in the clocks property.
 
-  - samsung,mfc-r : Base address of the first memory bank used by MFC
-   for DMA contiguous memory allocation and its size.
-
-  - samsung,mfc-l : Base address of the second memory bank used by MFC
-   for DMA contiguous memory allocation and its size.
-
 Optional properties:
   - power-domains : power-domain property defined with a phandle
   to respective power domain.
 
+  - memory-region : from reserved memory binding: phandles to two reserved
+   memory regions: accessed by "left" and "right" mfc memory bus
+   interfaces, used when no SYSMMU support is available
+  - memory-region-names : from reserved memory binding: must be "left"
+   and "right"
+
 Example:
 SoC specific DT entry:
 
@@ -46,6 +46,6 @@ mfc: codec@1340 {
 Board specific DT entry:
 
 codec@1340 {
-   samsung,mfc-r = <0x4300 0x80>;
-   samsung,mfc-l = <0x5100 0x80>;
+   memory-region = <_left>, <_right>;
+   memory-region-names = "left", "right";
 };
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts 
b/arch/arm/boot/dts/exynos4210-origen.dts
index b8f8669..5a5ec93 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -30,6 +30,24 @@
   0x7000 0x1000>;
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   mfc_left: region@5100 {
+   compatible = "shared-dma-pool";
+   no-map;
+   reg = <0x5100 0x80>;
+   };
+
+   mfc_right: region@4300 {
+   compatible = "shared-dma-pool";
+   no-map;
+   reg = <0x4300 0x80>;
+   };
+   };
+
chosen {
bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x4100,8M 
console=ttySAC2,115200 init=/linuxrc";
stdout-path = _2;
@@ -292,8 +310,8 @@
 };
 
  {
-   samsung,mfc-r = <0x4300 0x80>;
-   samsung,mfc-l = <0x5100 0x80>;
+   memory-region = <_left>, <_right>;
+   memory-region-names = "left", "right";
status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts 
b/arch/arm/boot/dts/exynos4210-smdkv310.dts
index bc1448b..0d204b7 100644
--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -26,6 +26,24 @@
reg = <0x4000 0x8000>;
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   mfc_left: region@5100 {
+   compatible = "shared-dma-pool";
+   no-map;
+ 

[PATCH v2 7/7] media: s5p-mfc: add iommu support

2015-12-09 Thread Marek Szyprowski
This patch adds support for IOMMU to s5p-mfc device driver. MFC firmware
is limited and it cannot use the default configuration. If IOMMU is
available, the patch disables the default DMA address space
configuration and creates a new address space of size limited to 256M
and base address set to 0x2000.

For now the same address space is shared by both 'left' and 'right'
memory channels, because the DMA/IOMMU frameworks do not support
configuring them separately. This is not optimal, but besides limiting
total address space available has no other drawbacks (MFC firmware
supports 256M of address space per each channel).

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 drivers/media/platform/s5p-mfc/s5p_mfc.c   | 24 
 drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h | 79 ++
 2 files changed, 103 insertions(+)
 create mode 100644 drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 3063449..bae7c0f 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -30,6 +30,7 @@
 #include "s5p_mfc_dec.h"
 #include "s5p_mfc_enc.h"
 #include "s5p_mfc_intr.h"
+#include "s5p_mfc_iommu.h"
 #include "s5p_mfc_opr.h"
 #include "s5p_mfc_cmd.h"
 #include "s5p_mfc_pm.h"
@@ -1061,6 +1062,22 @@ static int s5p_mfc_configure_dma_memory(struct 
s5p_mfc_dev *mfc_dev)
struct device *dev = _dev->plat_dev->dev;
 
/*
+* When IOMMU is available, we cannot use the default configuration,
+* because of MFC firmware requirements: address space limited to
+* 256M and non-zero default start address.
+* This is still simplified, not optimal configuration, but for now
+* IOMMU core doesn't allow to configure device's IOMMUs channel
+* separately.
+*/
+   if (exynos_is_iommu_available(dev)) {
+   int ret = exynos_configure_iommu(dev, S5P_MFC_IOMMU_DMA_BASE,
+S5P_MFC_IOMMU_DMA_SIZE);
+   if (ret == 0)
+   mfc_dev->mem_dev_l = mfc_dev->mem_dev_r = dev;
+   return ret;
+   }
+
+   /*
 * Create and initialize virtual devices for accessing
 * reserved memory regions.
 */
@@ -1078,6 +1095,13 @@ static int s5p_mfc_configure_dma_memory(struct 
s5p_mfc_dev *mfc_dev)
 
 static void s5p_mfc_unconfigure_dma_memory(struct s5p_mfc_dev *mfc_dev)
 {
+   struct device *dev = _dev->plat_dev->dev;
+
+   if (exynos_is_iommu_available(dev)) {
+   exynos_unconfigure_iommu(dev);
+   return;
+   }
+
device_unregister(mfc_dev->mem_dev_l);
device_unregister(mfc_dev->mem_dev_r);
 }
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h 
b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
new file mode 100644
index 000..5d1d1c2
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics Co.Ltd
+ * Authors: Marek Szyprowski <m.szyprow...@samsung.com>
+ *
+ * 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
+ * option) any later version.
+ */
+
+#ifndef S5P_MFC_IOMMU_H_
+#define S5P_MFC_IOMMU_H_
+
+#define S5P_MFC_IOMMU_DMA_BASE 0x2000lu
+#define S5P_MFC_IOMMU_DMA_SIZE SZ_256M
+
+#ifdef CONFIG_EXYNOS_IOMMU
+
+#include 
+
+static inline bool exynos_is_iommu_available(struct device *dev)
+{
+   return dev->archdata.iommu != NULL;
+}
+
+static inline void exynos_unconfigure_iommu(struct device *dev)
+{
+   struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+
+   arm_iommu_detach_device(dev);
+   arm_iommu_release_mapping(mapping);
+}
+
+static inline int exynos_configure_iommu(struct device *dev,
+unsigned int base, unsigned int size)
+{
+   struct dma_iommu_mapping *mapping = NULL;
+   int ret;
+
+   /* Disable the default mapping created by device core */
+   if (to_dma_iommu_mapping(dev))
+   exynos_unconfigure_iommu(dev);
+
+   mapping = arm_iommu_create_mapping(dev->bus, base, size);
+   if (IS_ERR(mapping)) {
+   pr_warn("Failed to create IOMMU mapping for device %s\n",
+   dev_name(dev));
+   return PTR_ERR(mapping);
+   }
+
+   ret = arm_iommu_attach_device(dev, mapping);
+   if (ret) {
+   pr_warn("Failed to attached device %s to IOMMU_mapping\n",
+   dev_name(dev));
+   arm_iommu_release_mapping(mapping);
+   

[PATCH v2 3/7] of: reserved_mem: add support for named reserved mem nodes

2015-12-09 Thread Marek Szyprowski
This patch allows device drivers to initialize more than one reserved
memory region assigned to given device. When driver needs to use more
than one reserved memory region, it should allocate child devices and
initialize regions by index or name for each of its child devices.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 drivers/of/of_reserved_mem.c| 104 
 include/linux/of_reserved_mem.h |  31 ++--
 2 files changed, 112 insertions(+), 23 deletions(-)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index be77e75..a583480 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MAX_RESERVED_REGIONS   16
 static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
@@ -281,53 +282,116 @@ static inline struct reserved_mem *__find_rmem(struct 
device_node *node)
return NULL;
 }
 
+struct rmem_assigned_device {
+   struct device *dev;
+   struct reserved_mem *rmem;
+   struct list_head list;
+};
+
+static LIST_HEAD(of_rmem_assigned_device_list);
+static DEFINE_MUTEX(of_rmem_assigned_device_mutex);
+
 /**
  * of_reserved_mem_device_init() - assign reserved memory region to given 
device
+ * @dev:   Pointer to the device to configure
+ * @np:Pointer to the device_node with 'reserved-memory' 
property
+ * @idx:   Index of selected region
+ *
+ * This function assigns respective DMA-mapping operations based on reserved
+ * memory region specified by 'memory-region' property in @np node to the @dev
+ * device. When driver needs to use more than one reserved memory region, it
+ * should allocate child devices and initialize regions by name for each of
+ * child device.
  *
- * This function assign memory region pointed by "memory-region" device tree
- * property to the given device.
+ * Returns error code or zero on success.
  */
-int of_reserved_mem_device_init(struct device *dev)
+int of_reserved_mem_init(struct device *dev, struct device_node *np, int idx)
 {
+   struct rmem_assigned_device *rd;
+   struct device_node *target;
struct reserved_mem *rmem;
-   struct device_node *np;
int ret;
 
-   np = of_parse_phandle(dev->of_node, "memory-region", 0);
-   if (!np)
-   return -ENODEV;
+   if (!np || !dev)
+   return -EINVAL;
+
+   target = of_parse_phandle(np, "memory-region", idx);
+   if (!target)
+   return -EINVAL;
 
-   rmem = __find_rmem(np);
-   of_node_put(np);
+   rmem = __find_rmem(target);
+   of_node_put(target);
 
if (!rmem || !rmem->ops || !rmem->ops->device_init)
return -EINVAL;
 
+   rd = kmalloc(sizeof(struct rmem_assigned_device), GFP_KERNEL);
+   if (!rd)
+   return -ENOMEM;
+
ret = rmem->ops->device_init(rmem, dev);
-   if (ret == 0)
+   if (ret == 0) {
+   rd->dev = dev;
+   rd->rmem = rmem;
+
+   mutex_lock(_rmem_assigned_device_mutex);
+   list_add(>list, _rmem_assigned_device_list);
+   mutex_unlock(_rmem_assigned_device_mutex);
+
dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
+   } else {
+   kfree(rd);
+   }
 
return ret;
 }
-EXPORT_SYMBOL_GPL(of_reserved_mem_device_init);
+EXPORT_SYMBOL_GPL(of_reserved_mem_init);
+
+/**
+ * of_reserved_mem_device_init() - assign reserved memory region to given 
device
+ * @dev:   Pointer to the device to configure
+ * @np:Pointer to the device_node with 'reserved-memory' 
property
+ * @name:  Name of the selected region
+ *
+ * This function assigns respective DMA-mapping operations based on reserved
+ * memory region specified by 'memory-region' property in @np node, named @name
+ * to the @dev device.
+ *
+ * Returns error code or zero on success.
+ */
+int of_reserved_mem_init_by_name(struct device *dev, struct device_node *np,
+  const char *name)
+{
+   int idx = of_property_match_string(np, "memory-region-names", name);
+
+   if (idx < 0)
+   return -EINVAL;
+   return of_reserved_mem_init(dev, np, idx);
+}
+EXPORT_SYMBOL_GPL(of_reserved_mem_init_by_name);
 
 /**
  * of_reserved_mem_device_release() - release reserved memory device structures
+ * @dev:   Pointer to the device to deconfigure
  *
  * This function releases structures allocated for memory region handling for
  * the given device.
  */
 void of_reserved_mem_device_release(struct device *dev)
 {
-   struct reserved_mem *rmem;
-   struct device_node *np;
-
-   np = of_parse_phandle(dev->of_node, "memory-region", 0);
-   if (!np)
-   return;
-
-   rm

[PATCH v2 5/7] media: set proper max seg size for devices on Exynos SoCs

2015-12-09 Thread Marek Szyprowski
All multimedia devices found on Exynos SoCs support only contiguous
buffers, so set DMA max segment size to DMA_BIT_MASK(32) to let memory
allocator to correctly create contiguous memory mappings.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 drivers/media/platform/exynos-gsc/gsc-core.c  | 1 +
 drivers/media/platform/exynos4-is/fimc-core.c | 1 +
 drivers/media/platform/exynos4-is/fimc-is.c   | 1 +
 drivers/media/platform/exynos4-is/fimc-lite.c | 1 +
 drivers/media/platform/s5p-g2d/g2d.c  | 1 +
 drivers/media/platform/s5p-jpeg/jpeg-core.c   | 1 +
 drivers/media/platform/s5p-mfc/s5p_mfc.c  | 2 ++
 drivers/media/platform/s5p-tv/mixer_video.c   | 1 +
 8 files changed, 9 insertions(+)

diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c 
b/drivers/media/platform/exynos-gsc/gsc-core.c
index 9b9e423..4f90be4 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.c
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -1140,6 +1140,7 @@ static int gsc_probe(struct platform_device *pdev)
goto err_m2m;
 
/* Initialize continious memory allocator */
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
gsc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(gsc->alloc_ctx)) {
ret = PTR_ERR(gsc->alloc_ctx);
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c 
b/drivers/media/platform/exynos4-is/fimc-core.c
index cef2a7f..368e19b 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/exynos4-is/fimc-core.c
@@ -1019,6 +1019,7 @@ static int fimc_probe(struct platform_device *pdev)
}
 
/* Initialize contiguous memory allocator */
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(fimc->alloc_ctx)) {
ret = PTR_ERR(fimc->alloc_ctx);
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c 
b/drivers/media/platform/exynos4-is/fimc-is.c
index 49658ca..123772f 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -841,6 +841,7 @@ static int fimc_is_probe(struct platform_device *pdev)
if (ret < 0)
goto err_pm;
 
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
is->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(is->alloc_ctx)) {
ret = PTR_ERR(is->alloc_ctx);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c 
b/drivers/media/platform/exynos4-is/fimc-lite.c
index 60660c3..a7e47c7 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1564,6 +1564,7 @@ static int fimc_lite_probe(struct platform_device *pdev)
goto err_sd;
}
 
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(fimc->alloc_ctx)) {
ret = PTR_ERR(fimc->alloc_ctx);
diff --git a/drivers/media/platform/s5p-g2d/g2d.c 
b/drivers/media/platform/s5p-g2d/g2d.c
index e1936d9..31f6c23 100644
--- a/drivers/media/platform/s5p-g2d/g2d.c
+++ b/drivers/media/platform/s5p-g2d/g2d.c
@@ -681,6 +681,7 @@ static int g2d_probe(struct platform_device *pdev)
goto put_clk_gate;
}
 
+   vb2_dma_contig_set_max_seg_size(>dev, DMA_BIT_MASK(32));
dev->alloc_ctx = vb2_dma_contig_init_ctx(>dev);
if (IS_ERR(dev->alloc_ctx)) {
ret = PTR_ERR(dev->alloc_ctx);
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 4a608cb..6bd92f0 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2839,6 +2839,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
goto device_register_rollback;
}
 
+   vb2_dma_contig_set_max_seg_size(>dev, DMA_BIT_MASK(32));
jpeg->alloc_ctx = vb2_dma_contig_init_ctx(>dev);
if (IS_ERR(jpeg->alloc_ctx)) {
v4l2_err(>v4l2_dev, "Failed to init memory allocator\n");
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 3ffe2ec..3e9cdaf 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1143,11 +1143,13 @@ static int s5p_mfc_probe(struct platform_device *pdev)
}
}
 
+   vb2_dma_contig_set_max_seg_size(dev->mem_dev_l, DMA_BIT_MASK(32));
dev->alloc_ctx[0] = vb2_dma_contig_init_ctx(dev->mem_dev_l);
if (IS_ERR(dev->alloc_ctx[0])) {
ret = PTR_ERR(dev->alloc_ctx[0]);
goto err_res;
}
+   vb2_dma_contig_set_max_seg_size(dev->mem_dev_r, DMA_BIT_MASK(32));
dev->alloc_ctx[

[PATCH v2 4/7] media: vb2-dma-contig: add helper for setting dma max seg size

2015-12-09 Thread Marek Szyprowski
Add a helper function for device drivers to set DMA's max_seg_size.
Setting it to largest possible value lets DMA-mapping API always create
contiguous mappings in DMA address space. This is essential for all
devices, which use dma-contig videobuf2 memory allocator and shared
buffers.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 15 +++
 include/media/videobuf2-dma-contig.h   |  1 +
 2 files changed, 16 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index c331272..628518d 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -742,6 +742,21 @@ void vb2_dma_contig_cleanup_ctx(void *alloc_ctx)
 }
 EXPORT_SYMBOL_GPL(vb2_dma_contig_cleanup_ctx);
 
+int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size)
+{
+   if (!dev->dma_parms) {
+   dev->dma_parms = devm_kzalloc(dev, sizeof(dev->dma_parms),
+ GFP_KERNEL);
+   if (!dev->dma_parms)
+   return -ENOMEM;
+   }
+   if (dma_get_max_seg_size(dev) < size)
+   return dma_set_max_seg_size(dev, size);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_dma_contig_set_max_seg_size);
+
 MODULE_DESCRIPTION("DMA-contig memory handling routines for videobuf2");
 MODULE_AUTHOR("Pawel Osciak <pa...@osciak.com>");
 MODULE_LICENSE("GPL");
diff --git a/include/media/videobuf2-dma-contig.h 
b/include/media/videobuf2-dma-contig.h
index c33dfa6..0e6ba64 100644
--- a/include/media/videobuf2-dma-contig.h
+++ b/include/media/videobuf2-dma-contig.h
@@ -26,6 +26,7 @@ vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned 
int plane_no)
 
 void *vb2_dma_contig_init_ctx(struct device *dev);
 void vb2_dma_contig_cleanup_ctx(void *alloc_ctx);
+int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size);
 
 extern const struct vb2_mem_ops vb2_dma_contig_memops;
 
-- 
1.9.2

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


[PATCH v2 6/7] media: s5p-mfc: replace custom reserved memory init code with generic one

2015-12-09 Thread Marek Szyprowski
This patch removes custom code for initialization and handling of
reserved memory regions in s5p-mfc driver and replaces it with generic
named reserved memory regions specified in device tree.

s5p-mfc driver now handles two reserved memory regions: "left" and
"right", defined by generic reserved memory bindings. Support for non-dt
platform has been removed, because all supported platforms have been
converted to device tree.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 drivers/media/platform/s5p-mfc/s5p_mfc.c | 129 +++
 1 file changed, 62 insertions(+), 67 deletions(-)

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 3e9cdaf..3063449 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "s5p_mfc_common.h"
 #include "s5p_mfc_ctrl.h"
@@ -1022,55 +1023,67 @@ static const struct v4l2_file_operations s5p_mfc_fops = 
{
.mmap = s5p_mfc_mmap,
 };
 
-static int match_child(struct device *dev, void *data)
+/* DMA memory related helper functions */
+static void s5p_mfc_memdev_release(struct device *dev)
 {
-   if (!dev_name(dev))
-   return 0;
-   return !strcmp(dev_name(dev), (char *)data);
+   of_reserved_mem_device_release(dev);
 }
 
-static void *mfc_get_drv_data(struct platform_device *pdev);
-
-static int s5p_mfc_alloc_memdevs(struct s5p_mfc_dev *dev)
+static struct device *s5p_mfc_alloc_memdev(struct device *dev, const char 
*name)
 {
-   unsigned int mem_info[2] = { };
+   struct device *child;
+   int ret;
 
-   dev->mem_dev_l = devm_kzalloc(>plat_dev->dev,
-   sizeof(struct device), GFP_KERNEL);
-   if (!dev->mem_dev_l) {
-   mfc_err("Not enough memory\n");
-   return -ENOMEM;
-   }
-   device_initialize(dev->mem_dev_l);
-   of_property_read_u32_array(dev->plat_dev->dev.of_node,
-   "samsung,mfc-l", mem_info, 2);
-   if (dma_declare_coherent_memory(dev->mem_dev_l, mem_info[0],
-   mem_info[0], mem_info[1],
-   DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) {
-   mfc_err("Failed to declare coherent memory for\n"
-   "MFC device\n");
-   return -ENOMEM;
+   child = devm_kzalloc(dev, sizeof(struct device), GFP_KERNEL);
+   if (!child)
+   return NULL;
+
+   device_initialize(child);
+   dev_set_name(child, "%s:%s", dev_name(dev), name);
+   child->parent = dev;
+   child->bus = dev->bus;
+   child->coherent_dma_mask = dev->coherent_dma_mask;
+   child->dma_mask = dev->dma_mask;
+   child->release = s5p_mfc_memdev_release;
+
+   if (device_add(child) == 0) {
+   ret = of_reserved_mem_init_by_name(child, dev->of_node, name);
+   if (ret == 0)
+   return child;
}
 
-   dev->mem_dev_r = devm_kzalloc(>plat_dev->dev,
-   sizeof(struct device), GFP_KERNEL);
-   if (!dev->mem_dev_r) {
-   mfc_err("Not enough memory\n");
-   return -ENOMEM;
-   }
-   device_initialize(dev->mem_dev_r);
-   of_property_read_u32_array(dev->plat_dev->dev.of_node,
-   "samsung,mfc-r", mem_info, 2);
-   if (dma_declare_coherent_memory(dev->mem_dev_r, mem_info[0],
-   mem_info[0], mem_info[1],
-   DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) {
-   pr_err("Failed to declare coherent memory for\n"
-   "MFC device\n");
-   return -ENOMEM;
+   put_device(child);
+   return NULL;
+}
+
+static int s5p_mfc_configure_dma_memory(struct s5p_mfc_dev *mfc_dev)
+{
+   struct device *dev = _dev->plat_dev->dev;
+
+   /*
+* Create and initialize virtual devices for accessing
+* reserved memory regions.
+*/
+   mfc_dev->mem_dev_l = s5p_mfc_alloc_memdev(dev, "left");
+   if (!mfc_dev->mem_dev_l)
+   return -ENODEV;
+   mfc_dev->mem_dev_r = s5p_mfc_alloc_memdev(dev, "right");
+   if (!mfc_dev->mem_dev_r) {
+   device_unregister(mfc_dev->mem_dev_l);
+   return -ENODEV;
}
+
return 0;
 }
 
+static void s5p_mfc_unconfigure_dma_memory(struct s5p_mfc_dev *mfc_dev)
+{
+   device_unregister(mfc_dev->mem_dev_l);
+   device_unregister(mfc_dev->mem_dev_r);
+}
+
+static void *mfc_get_drv_data(struct platform_device *pdev);
+
 /* MFC probe function */
 static int s5p_mfc_probe(

[PATCH v2 2/7] ARM: dts: exynos4412-odroid*: enable MFC device

2015-12-09 Thread Marek Szyprowski
Enable support for Multimedia Codec (MFC) device for all Exynos4412-based
Odroid boards.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 24 
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi 
b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index edf0fc8..5825abf 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -18,6 +18,24 @@
stdout-path = _1;
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   mfc_left: region@7700 {
+   compatible = "shared-dma-pool";
+   reusable;
+   reg = <0x7700 0x100>;
+   };
+
+   mfc_right: region@7800 {
+   compatible = "shared-dma-pool";
+   reusable;
+   reg = <0x7800 0x100>;
+   };
+   };
+
firmware@0204F000 {
compatible = "samsung,secure-firmware";
reg = <0x0204F000 0x1000>;
@@ -451,6 +469,12 @@
clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
 };
 
+ {
+   memory-region = <_left>, <_right>;
+   memory-region-names = "left", "right";
+   status = "okay";
+};
+
  {
status = "okay";
 };
-- 
1.9.2

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


Re: [PATCH 0/7] Exynos: MFC driver: reserved memory cleanup and IOMMU support

2015-12-08 Thread Marek Szyprowski

Hello,

On 2015-12-07 13:08, Marek Szyprowski wrote:

This patchset finally perform cleanup of custom code in s5p-mfc codec
driver. The first part is removal of custom, driver specific code for
intializing and handling of reserved memory. Instead, a generic code for
reserved memory regions is used. Then, once it is done, the proper setup
of DMA parameters (max segment size) is applied for all multimedia
devices found on Exynos SoCs to let them properly handle shared buffers
mapped into contiguous DMA address space. The last patch adds support
for IOMMU to MFC driver. Some additional code is needed because of
specific requirements of MFC device firmware (see patch 7 for more
details). When no IOMMU is available, the code fallbacks to generic
reserved memory regions.

After applying this patchset, MFC device works correctly when IOMMU is
either enabled or disabled.

Patches have been tested on top of linux-next from 20151207. I would
prefer to merge patches 1-2 via Samsung tree and patches 3-7 via media
tree (there are no compile-time dependencies between patches 1-2 and
3-7). Patches have been tested on Odroid U3 (Exynos 4412 based) and
Odroid XU3 (Exynos 5422 based) boards.


One more notice: this is an updated version of the old patch initially
posted here:
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-August/189259.html

The main change since that is adaptation for generic reserved memory
bindings, which have been merged a while ago and added support for IOMMU.

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

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


[PATCH 3/7] of: reserved_mem: add support for named reserved mem nodes

2015-12-07 Thread Marek Szyprowski
This patch allows device drivers to use more than one reserved memory
region assigned to given device. When NULL name is passed to
of_reserved_mem_device_init(), the default (first) region is used.

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

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 1a3556a9e9ea..0a0b23b73004 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MAX_RESERVED_REGIONS   16
 static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
@@ -287,31 +288,84 @@ static inline struct reserved_mem *__find_rmem(struct 
device_node *node)
return NULL;
 }
 
+static struct reserved_mem *__node_to_rmem(struct device_node *node,
+  const char *name)
+{
+   struct reserved_mem *rmem;
+   struct device_node *target;
+   int idx = 0;
+
+   if (!node)
+   return NULL;
+
+   if (name) {
+   idx = of_property_match_string(node,
+  "memory-region-names", name);
+   if (idx < 0)
+   return NULL;
+   }
+
+   target = of_parse_phandle(node, "memory-region", idx);
+   if (!target)
+   return NULL;
+   rmem = __find_rmem(target);
+   of_node_put(target);
+
+   return rmem;
+}
+
+struct rmem_assigned_device {
+   struct device *dev;
+   struct reserved_mem *rmem;
+   struct list_head list;
+};
+
+static LIST_HEAD(of_rmem_assigned_device_list);
+static DEFINE_MUTEX(of_rmem_assigned_device_mutex);
+
 /**
  * of_reserved_mem_device_init() - assign reserved memory region to given 
device
+ * @dev:   Pointer to the device to configure
+ * @np:Pointer to the device_node with 'reserved-memory' 
property
+ * @name:  Optional name of the selected region (can be NULL)
+ *
+ * This function assigns respective DMA-mapping operations based on reserved
+ * memory regionspecified by 'memory-region' property in @np node, named @name
+ * to the @dev device. When NULL name is provided, the default (first) memory
+ * region is used. When driver needs to use more than one reserved memory
+ * region, it should allocate child devices and initialize regions by name for
+ * each of child device.
  *
- * This function assign memory region pointed by "memory-region" device tree
- * property to the given device.
+ * Returns error code or zero on success.
  */
-int of_reserved_mem_device_init(struct device *dev)
+int of_reserved_mem_device_init(struct device *dev, struct device_node *np,
+   const char *name)
 {
+   struct rmem_assigned_device *rd;
struct reserved_mem *rmem;
-   struct device_node *np;
int ret;
 
-   np = of_parse_phandle(dev->of_node, "memory-region", 0);
-   if (!np)
-   return -ENODEV;
-
-   rmem = __find_rmem(np);
-   of_node_put(np);
-
+   rmem = __node_to_rmem(np, name);
if (!rmem || !rmem->ops || !rmem->ops->device_init)
return -EINVAL;
 
+   rd = kmalloc(sizeof(struct rmem_assigned_device), GFP_KERNEL);
+   if (!rd)
+   return -ENOMEM;
+
ret = rmem->ops->device_init(rmem, dev);
-   if (ret == 0)
+   if (ret == 0) {
+   rd->dev = dev;
+   rd->rmem = rmem;
+
+   mutex_lock(_rmem_assigned_device_mutex);
+   list_add(>list, _rmem_assigned_device_list);
+   mutex_unlock(_rmem_assigned_device_mutex);
+
dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
+   } else {
+   kfree(rd);
+   }
 
return ret;
 }
@@ -319,21 +373,26 @@ EXPORT_SYMBOL_GPL(of_reserved_mem_device_init);
 
 /**
  * of_reserved_mem_device_release() - release reserved memory device structures
+ * @dev:   Pointer to the device to deconfigure
  *
  * This function releases structures allocated for memory region handling for
  * the given device.
  */
 void of_reserved_mem_device_release(struct device *dev)
 {
-   struct reserved_mem *rmem;
-   struct device_node *np;
-
-   np = of_parse_phandle(dev->of_node, "memory-region", 0);
-   if (!np)
-   return;
-
-   rmem = __find_rmem(np);
-   of_node_put(np);
+   struct rmem_assigned_device *rd;
+   struct reserved_mem *rmem = NULL;
+
+   mutex_lock(_rmem_assigned_device_mutex);
+   list_for_each_entry(rd, _rmem_assigned_device_list, list) {
+   if (rd->dev == dev) {
+   rmem = rd->rme

[PATCH 5/7] media: set proper max seg size for devices on Exynos SoCs

2015-12-07 Thread Marek Szyprowski
All multimedia devices found on Exynos SoCs support only contiguous
buffers, so set DMA max segment size to DMA_BIT_MASK(32) to let memory
allocator to correctly create contiguous memory mappings.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 drivers/media/platform/exynos-gsc/gsc-core.c  | 1 +
 drivers/media/platform/exynos4-is/fimc-core.c | 1 +
 drivers/media/platform/exynos4-is/fimc-is.c   | 1 +
 drivers/media/platform/exynos4-is/fimc-lite.c | 1 +
 drivers/media/platform/s5p-g2d/g2d.c  | 1 +
 drivers/media/platform/s5p-jpeg/jpeg-core.c   | 1 +
 drivers/media/platform/s5p-mfc/s5p_mfc.c  | 2 ++
 drivers/media/platform/s5p-tv/mixer_video.c   | 1 +
 8 files changed, 9 insertions(+)

diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c 
b/drivers/media/platform/exynos-gsc/gsc-core.c
index 9b9e423e4fc4..4f90be43b5a9 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.c
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -1140,6 +1140,7 @@ static int gsc_probe(struct platform_device *pdev)
goto err_m2m;
 
/* Initialize continious memory allocator */
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
gsc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(gsc->alloc_ctx)) {
ret = PTR_ERR(gsc->alloc_ctx);
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c 
b/drivers/media/platform/exynos4-is/fimc-core.c
index cef2a7f07cdb..368e19b50498 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/exynos4-is/fimc-core.c
@@ -1019,6 +1019,7 @@ static int fimc_probe(struct platform_device *pdev)
}
 
/* Initialize contiguous memory allocator */
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(fimc->alloc_ctx)) {
ret = PTR_ERR(fimc->alloc_ctx);
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c 
b/drivers/media/platform/exynos4-is/fimc-is.c
index 49658ca39e51..123772fa0241 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -841,6 +841,7 @@ static int fimc_is_probe(struct platform_device *pdev)
if (ret < 0)
goto err_pm;
 
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
is->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(is->alloc_ctx)) {
ret = PTR_ERR(is->alloc_ctx);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c 
b/drivers/media/platform/exynos4-is/fimc-lite.c
index 6f76afd909c4..9cfd2221f53d 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1564,6 +1564,7 @@ static int fimc_lite_probe(struct platform_device *pdev)
goto err_sd;
}
 
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(fimc->alloc_ctx)) {
ret = PTR_ERR(fimc->alloc_ctx);
diff --git a/drivers/media/platform/s5p-g2d/g2d.c 
b/drivers/media/platform/s5p-g2d/g2d.c
index e1936d9d27da..31f6c233b146 100644
--- a/drivers/media/platform/s5p-g2d/g2d.c
+++ b/drivers/media/platform/s5p-g2d/g2d.c
@@ -681,6 +681,7 @@ static int g2d_probe(struct platform_device *pdev)
goto put_clk_gate;
}
 
+   vb2_dma_contig_set_max_seg_size(>dev, DMA_BIT_MASK(32));
dev->alloc_ctx = vb2_dma_contig_init_ctx(>dev);
if (IS_ERR(dev->alloc_ctx)) {
ret = PTR_ERR(dev->alloc_ctx);
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 4a608cbe0fdb..6bd92f014a23 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2839,6 +2839,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
goto device_register_rollback;
}
 
+   vb2_dma_contig_set_max_seg_size(>dev, DMA_BIT_MASK(32));
jpeg->alloc_ctx = vb2_dma_contig_init_ctx(>dev);
if (IS_ERR(jpeg->alloc_ctx)) {
v4l2_err(>v4l2_dev, "Failed to init memory allocator\n");
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 81ffb67e6d66..8fcecf8a9a17 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1164,11 +1164,13 @@ static int s5p_mfc_probe(struct platform_device *pdev)
}
}
 
+   vb2_dma_contig_set_max_seg_size(dev->mem_dev_l, DMA_BIT_MASK(32));
dev->alloc_ctx[0] = vb2_dma_contig_init_ctx(dev->mem_dev_l);
if (IS_ERR(dev->alloc_ctx[0])) {
ret = PTR_ERR(dev->alloc_ctx[0]);
goto err_res;
}
+   vb2_dma_contig_set_max

[PATCH 6/7] media: s5p-mfc: replace custom reserved memory init code with generic one

2015-12-07 Thread Marek Szyprowski
This patch removes custom code for initialization and handling of
reserved memory regions in s5p-mfc driver and replaces it with generic
named reserved memory regions specified in device tree.

s5p-mfc driver now handles two reserved memory regions: "left" and
"right", defined by generic reserved memory bindings. Support for non-dt
platform has been removed, because all supported platforms have been
converted to device tree.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 drivers/media/platform/s5p-mfc/s5p_mfc.c | 129 +++
 1 file changed, 62 insertions(+), 67 deletions(-)

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 8fcecf8a9a17..55c557f835f2 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "s5p_mfc_common.h"
 #include "s5p_mfc_ctrl.h"
@@ -1043,55 +1044,67 @@ static const struct v4l2_file_operations s5p_mfc_fops = 
{
.mmap = s5p_mfc_mmap,
 };
 
-static int match_child(struct device *dev, void *data)
+/* DMA memory related helper functions */
+static void s5p_mfc_memdev_release(struct device *dev)
 {
-   if (!dev_name(dev))
-   return 0;
-   return !strcmp(dev_name(dev), (char *)data);
+   of_reserved_mem_device_release(dev);
 }
 
-static void *mfc_get_drv_data(struct platform_device *pdev);
-
-static int s5p_mfc_alloc_memdevs(struct s5p_mfc_dev *dev)
+static struct device *s5p_mfc_alloc_memdev(struct device *dev, const char 
*name)
 {
-   unsigned int mem_info[2] = { };
+   struct device *child;
+   int ret;
 
-   dev->mem_dev_l = devm_kzalloc(>plat_dev->dev,
-   sizeof(struct device), GFP_KERNEL);
-   if (!dev->mem_dev_l) {
-   mfc_err("Not enough memory\n");
-   return -ENOMEM;
-   }
-   device_initialize(dev->mem_dev_l);
-   of_property_read_u32_array(dev->plat_dev->dev.of_node,
-   "samsung,mfc-l", mem_info, 2);
-   if (dma_declare_coherent_memory(dev->mem_dev_l, mem_info[0],
-   mem_info[0], mem_info[1],
-   DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) {
-   mfc_err("Failed to declare coherent memory for\n"
-   "MFC device\n");
-   return -ENOMEM;
+   child = devm_kzalloc(dev, sizeof(struct device), GFP_KERNEL);
+   if (!child)
+   return NULL;
+
+   device_initialize(child);
+   dev_set_name(child, "%s:%s", dev_name(dev), name);
+   child->parent = dev;
+   child->bus = dev->bus;
+   child->coherent_dma_mask = dev->coherent_dma_mask;
+   child->dma_mask = dev->dma_mask;
+   child->release = s5p_mfc_memdev_release;
+
+   if (device_add(child) == 0) {
+   ret = of_reserved_mem_device_init(child, dev->of_node, name);
+   if (ret == 0)
+   return child;
}
 
-   dev->mem_dev_r = devm_kzalloc(>plat_dev->dev,
-   sizeof(struct device), GFP_KERNEL);
-   if (!dev->mem_dev_r) {
-   mfc_err("Not enough memory\n");
-   return -ENOMEM;
-   }
-   device_initialize(dev->mem_dev_r);
-   of_property_read_u32_array(dev->plat_dev->dev.of_node,
-   "samsung,mfc-r", mem_info, 2);
-   if (dma_declare_coherent_memory(dev->mem_dev_r, mem_info[0],
-   mem_info[0], mem_info[1],
-   DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) {
-   pr_err("Failed to declare coherent memory for\n"
-   "MFC device\n");
-   return -ENOMEM;
+   put_device(child);
+   return NULL;
+}
+
+static int s5p_mfc_configure_dma_memory(struct s5p_mfc_dev *mfc_dev)
+{
+   struct device *dev = _dev->plat_dev->dev;
+
+   /*
+* Create and initialize virtual devices for accessing
+* reserved memory regions.
+*/
+   mfc_dev->mem_dev_l = s5p_mfc_alloc_memdev(dev, "left");
+   if (!mfc_dev->mem_dev_l)
+   return -ENODEV;
+   mfc_dev->mem_dev_r = s5p_mfc_alloc_memdev(dev, "right");
+   if (!mfc_dev->mem_dev_r) {
+   device_unregister(mfc_dev->mem_dev_l);
+   return -ENODEV;
}
+
return 0;
 }
 
+static void s5p_mfc_unconfigure_dma_memory(struct s5p_mfc_dev *mfc_dev)
+{
+   device_unregister(mfc_dev->mem_dev_l);
+   device_unregister(mfc_dev->mem_dev_r);
+}
+
+static void *mfc_get_drv_data(struct platform_device *pdev);
+
 /* MFC probe function */
 static int s5p_m

[PATCH 1/7] ARM: Exynos: convert MFC device to generic reserved memory bindings

2015-12-07 Thread Marek Szyprowski
This patch replaces custom properties for definining reserved memory
regions with generic reserved memory bindings. All custom code for
handling MFC-specific reserved memory can be now removed from Exynos-DT
generic board code.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 .../devicetree/bindings/media/s5p-mfc.txt  | 16 ++--
 arch/arm/boot/dts/exynos4210-origen.dts| 22 -
 arch/arm/boot/dts/exynos4210-smdkv310.dts  | 22 -
 arch/arm/boot/dts/exynos4412-origen.dts| 22 -
 arch/arm/boot/dts/exynos4412-smdk4412.dts  | 22 -
 arch/arm/boot/dts/exynos5250-arndale.dts   | 22 -
 arch/arm/boot/dts/exynos5250-smdk5250.dts  | 22 -
 arch/arm/boot/dts/exynos5250-spring.dts| 22 -
 arch/arm/boot/dts/exynos5420-arndale-octa.dts  | 22 -
 arch/arm/boot/dts/exynos5420-smdk5420.dts  | 22 -
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi | 22 -
 arch/arm/mach-exynos/Makefile  |  2 -
 arch/arm/mach-exynos/exynos.c  | 19 -
 arch/arm/mach-exynos/mfc.h | 16 
 arch/arm/mach-exynos/s5p-dev-mfc.c | 94 --
 15 files changed, 208 insertions(+), 159 deletions(-)
 delete mode 100644 arch/arm/mach-exynos/mfc.h
 delete mode 100644 arch/arm/mach-exynos/s5p-dev-mfc.c

diff --git a/Documentation/devicetree/bindings/media/s5p-mfc.txt 
b/Documentation/devicetree/bindings/media/s5p-mfc.txt
index 2d5787eac91a..4603673c593b 100644
--- a/Documentation/devicetree/bindings/media/s5p-mfc.txt
+++ b/Documentation/devicetree/bindings/media/s5p-mfc.txt
@@ -21,16 +21,16 @@ Required properties:
   - clock-names : from common clock binding: must contain "mfc",
  corresponding to entry in the clocks property.
 
-  - samsung,mfc-r : Base address of the first memory bank used by MFC
-   for DMA contiguous memory allocation and its size.
-
-  - samsung,mfc-l : Base address of the second memory bank used by MFC
-   for DMA contiguous memory allocation and its size.
-
 Optional properties:
   - power-domains : power-domain property defined with a phandle
   to respective power domain.
 
+  - memory-region : from reserved memory binding: phandles to two reserved
+   memory regions: accessed by "left" and "right" mfc memory bus
+   interfaces, used when no SYSMMU support is available
+  - memory-region-names : from reserved memory binding: must be "left"
+   and "right"
+
 Example:
 SoC specific DT entry:
 
@@ -46,6 +46,6 @@ mfc: codec@1340 {
 Board specific DT entry:
 
 codec@1340 {
-   samsung,mfc-r = <0x4300 0x80>;
-   samsung,mfc-l = <0x5100 0x80>;
+   memory-region = <_left>, <_right>;
+   memory-region-names = "left", "right";
 };
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts 
b/arch/arm/boot/dts/exynos4210-origen.dts
index 5821ad87e32c..4b7637dfa392 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -30,6 +30,24 @@
   0x7000 0x1000>;
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   mfc_left: region@5100 {
+   compatible = "shared-dma-pool";
+   no-map;
+   reg = <0x5100 0x80>;
+   };
+
+   mfc_right: region@4300 {
+   compatible = "shared-dma-pool";
+   no-map;
+   reg = <0x4300 0x80>;
+   };
+   };
+
chosen {
bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x4100,8M 
console=ttySAC2,115200 init=/linuxrc";
stdout-path = _2;
@@ -288,8 +306,8 @@
 };
 
  {
-   samsung,mfc-r = <0x4300 0x80>;
-   samsung,mfc-l = <0x5100 0x80>;
+   memory-region = <_left>, <_right>;
+   memory-region-names = "left", "right";
status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts 
b/arch/arm/boot/dts/exynos4210-smdkv310.dts
index 104cbb33d2bb..efafc5721817 100644
--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -26,6 +26,24 @@
reg = <0x4000 0x8000>;
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   mfc_left: region@5100 {
+   compatible = "shared-dma-pool";
+   no-map;
+

[PATCH 4/7] media: vb2-dma-contig: add helper for setting dma max seg size

2015-12-07 Thread Marek Szyprowski
Add a helper function for device drivers to set DMA's max_seg_size.
Setting it to largest possible value lets DMA-mapping API always create
contiguous mappings in DMA address space. This is essential for all
devices, which use dma-contig videobuf2 memory allocator and shared
buffers.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
Changelog:
v3:
- make this code a helper function instead of chaning max_seg_size
  unconditionally on vb2_dma_contig_init_ctx

v2:
- set max segment size only if a new dma params structure has been
  allocated, as suggested by Laurent Pinchart
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 15 +++
 include/media/videobuf2-dma-contig.h   |  1 +
 2 files changed, 16 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index c33127284cfe..628518dc3aad 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -742,6 +742,21 @@ void vb2_dma_contig_cleanup_ctx(void *alloc_ctx)
 }
 EXPORT_SYMBOL_GPL(vb2_dma_contig_cleanup_ctx);
 
+int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size)
+{
+   if (!dev->dma_parms) {
+   dev->dma_parms = devm_kzalloc(dev, sizeof(dev->dma_parms),
+ GFP_KERNEL);
+   if (!dev->dma_parms)
+   return -ENOMEM;
+   }
+   if (dma_get_max_seg_size(dev) < size)
+   return dma_set_max_seg_size(dev, size);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_dma_contig_set_max_seg_size);
+
 MODULE_DESCRIPTION("DMA-contig memory handling routines for videobuf2");
 MODULE_AUTHOR("Pawel Osciak <pa...@osciak.com>");
 MODULE_LICENSE("GPL");
diff --git a/include/media/videobuf2-dma-contig.h 
b/include/media/videobuf2-dma-contig.h
index c33dfa69d7ab..0e6ba644939e 100644
--- a/include/media/videobuf2-dma-contig.h
+++ b/include/media/videobuf2-dma-contig.h
@@ -26,6 +26,7 @@ vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned 
int plane_no)
 
 void *vb2_dma_contig_init_ctx(struct device *dev);
 void vb2_dma_contig_cleanup_ctx(void *alloc_ctx);
+int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size);
 
 extern const struct vb2_mem_ops vb2_dma_contig_memops;
 
-- 
1.9.2

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


[PATCH 0/7] Exynos: MFC driver: reserved memory cleanup and IOMMU support

2015-12-07 Thread Marek Szyprowski
Hello,

This patchset finally perform cleanup of custom code in s5p-mfc codec
driver. The first part is removal of custom, driver specific code for
intializing and handling of reserved memory. Instead, a generic code for
reserved memory regions is used. Then, once it is done, the proper setup
of DMA parameters (max segment size) is applied for all multimedia
devices found on Exynos SoCs to let them properly handle shared buffers
mapped into contiguous DMA address space. The last patch adds support
for IOMMU to MFC driver. Some additional code is needed because of
specific requirements of MFC device firmware (see patch 7 for more
details). When no IOMMU is available, the code fallbacks to generic
reserved memory regions.

After applying this patchset, MFC device works correctly when IOMMU is
either enabled or disabled.

Patches have been tested on top of linux-next from 20151207. I would
prefer to merge patches 1-2 via Samsung tree and patches 3-7 via media
tree (there are no compile-time dependencies between patches 1-2 and
3-7). Patches have been tested on Odroid U3 (Exynos 4412 based) and
Odroid XU3 (Exynos 5422 based) boards.

Best regards
Marek Szyprowski
Samsung R Institute Poland


Patch summary:

Marek Szyprowski (7):
  ARM: Exynos: convert MFC device to generic reserved memory bindings
  ARM: dts: exynos4412-odroid*: enable MFC device
  of: reserved_mem: add support for named reserved mem nodes
  media: vb2-dma-contig: add helper for setting dma max seg size
  media: set proper max seg size for devices on Exynos SoCs
  media: s5p-mfc: replace custom reserved memory init code with generic
one
  media: s5p-mfc: add iommu support

 .../devicetree/bindings/media/s5p-mfc.txt  |  16 +--
 arch/arm/boot/dts/exynos4210-origen.dts|  22 ++-
 arch/arm/boot/dts/exynos4210-smdkv310.dts  |  22 ++-
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi|  24 
 arch/arm/boot/dts/exynos4412-origen.dts|  22 ++-
 arch/arm/boot/dts/exynos4412-smdk4412.dts  |  22 ++-
 arch/arm/boot/dts/exynos5250-arndale.dts   |  22 ++-
 arch/arm/boot/dts/exynos5250-smdk5250.dts  |  22 ++-
 arch/arm/boot/dts/exynos5250-spring.dts|  22 ++-
 arch/arm/boot/dts/exynos5420-arndale-octa.dts  |  22 ++-
 arch/arm/boot/dts/exynos5420-smdk5420.dts  |  22 ++-
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |  22 ++-
 arch/arm/mach-exynos/Makefile  |   2 -
 arch/arm/mach-exynos/exynos.c  |  19 ---
 arch/arm/mach-exynos/mfc.h |  16 ---
 arch/arm/mach-exynos/s5p-dev-mfc.c |  94 -
 drivers/media/platform/exynos-gsc/gsc-core.c   |   1 +
 drivers/media/platform/exynos4-is/fimc-core.c  |   1 +
 drivers/media/platform/exynos4-is/fimc-is.c|   1 +
 drivers/media/platform/exynos4-is/fimc-lite.c  |   1 +
 drivers/media/platform/s5p-g2d/g2d.c   |   1 +
 drivers/media/platform/s5p-jpeg/jpeg-core.c|   1 +
 drivers/media/platform/s5p-mfc/s5p_mfc.c   | 153 -
 drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h |  79 +++
 drivers/media/platform/s5p-tv/mixer_video.c|   1 +
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  15 ++
 drivers/of/of_reserved_mem.c   | 101 +++---
 include/linux/of_reserved_mem.h|   6 +-
 include/media/videobuf2-dma-contig.h   |   1 +
 29 files changed, 505 insertions(+), 248 deletions(-)
 delete mode 100644 arch/arm/mach-exynos/mfc.h
 delete mode 100644 arch/arm/mach-exynos/s5p-dev-mfc.c
 create mode 100644 drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h

-- 
1.9.2

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


[PATCH 7/7] media: s5p-mfc: add iommu support

2015-12-07 Thread Marek Szyprowski
This patch adds support for IOMMU to s5p-mfc device driver. MFC firmware
is limited and it cannot use the default configuration. If IOMMU is
available, the patch disables the default DMA address space
configuration and creates a new address space of size limited to 256M
and base address set to 0x2000.

For now the same address space is shared by both 'left' and 'right'
memory channels, because the DMA/IOMMU frameworks do not support
configuring them separately. This is not optimal, but besides limiting
total address space available has no other drawbacks (MFC firmware
supports 256M of address space per each channel).

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 drivers/media/platform/s5p-mfc/s5p_mfc.c   | 24 
 drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h | 79 ++
 2 files changed, 103 insertions(+)
 create mode 100644 drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 55c557f835f2..dfbaadd22a3d 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -30,6 +30,7 @@
 #include "s5p_mfc_dec.h"
 #include "s5p_mfc_enc.h"
 #include "s5p_mfc_intr.h"
+#include "s5p_mfc_iommu.h"
 #include "s5p_mfc_opr.h"
 #include "s5p_mfc_cmd.h"
 #include "s5p_mfc_pm.h"
@@ -1082,6 +1083,22 @@ static int s5p_mfc_configure_dma_memory(struct 
s5p_mfc_dev *mfc_dev)
struct device *dev = _dev->plat_dev->dev;
 
/*
+* When IOMMU is available, we cannot use the default configuration,
+* because of MFC firmware requirements: address space limited to
+* 256M and non-zero default start address.
+* This is still simplified, not optimal configuration, but for now
+* IOMMU core doesn't allow to configure device's IOMMUs channel
+* separately.
+*/
+   if (exynos_is_iommu_available(dev)) {
+   int ret = exynos_configure_iommu(dev, S5P_MFC_IOMMU_DMA_BASE,
+S5P_MFC_IOMMU_DMA_SIZE);
+   if (ret == 0)
+   mfc_dev->mem_dev_l = mfc_dev->mem_dev_r = dev;
+   return ret;
+   }
+
+   /*
 * Create and initialize virtual devices for accessing
 * reserved memory regions.
 */
@@ -1099,6 +1116,13 @@ static int s5p_mfc_configure_dma_memory(struct 
s5p_mfc_dev *mfc_dev)
 
 static void s5p_mfc_unconfigure_dma_memory(struct s5p_mfc_dev *mfc_dev)
 {
+   struct device *dev = _dev->plat_dev->dev;
+
+   if (exynos_is_iommu_available(dev)) {
+   exynos_unconfigure_iommu(dev);
+   return;
+   }
+
device_unregister(mfc_dev->mem_dev_l);
device_unregister(mfc_dev->mem_dev_r);
 }
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h 
b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
new file mode 100644
index ..5d1d1c2922e8
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics Co.Ltd
+ * Authors: Marek Szyprowski <m.szyprow...@samsung.com>
+ *
+ * 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
+ * option) any later version.
+ */
+
+#ifndef S5P_MFC_IOMMU_H_
+#define S5P_MFC_IOMMU_H_
+
+#define S5P_MFC_IOMMU_DMA_BASE 0x2000lu
+#define S5P_MFC_IOMMU_DMA_SIZE SZ_256M
+
+#ifdef CONFIG_EXYNOS_IOMMU
+
+#include 
+
+static inline bool exynos_is_iommu_available(struct device *dev)
+{
+   return dev->archdata.iommu != NULL;
+}
+
+static inline void exynos_unconfigure_iommu(struct device *dev)
+{
+   struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+
+   arm_iommu_detach_device(dev);
+   arm_iommu_release_mapping(mapping);
+}
+
+static inline int exynos_configure_iommu(struct device *dev,
+unsigned int base, unsigned int size)
+{
+   struct dma_iommu_mapping *mapping = NULL;
+   int ret;
+
+   /* Disable the default mapping created by device core */
+   if (to_dma_iommu_mapping(dev))
+   exynos_unconfigure_iommu(dev);
+
+   mapping = arm_iommu_create_mapping(dev->bus, base, size);
+   if (IS_ERR(mapping)) {
+   pr_warn("Failed to create IOMMU mapping for device %s\n",
+   dev_name(dev));
+   return PTR_ERR(mapping);
+   }
+
+   ret = arm_iommu_attach_device(dev, mapping);
+   if (ret) {
+   pr_warn("Failed to attached device %s to IOMMU_mapping\n",
+   dev_name(dev));
+   arm_iommu_release_mapping(mapping);

[PATCH 2/7] ARM: dts: exynos4412-odroid*: enable MFC device

2015-12-07 Thread Marek Szyprowski
Enable support for Multimedia Codec (MFC) device for all Exynos4412-based
Odroid boards.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 24 
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi 
b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index 395c3ca9601e..90b952e29ebf 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -18,6 +18,24 @@
stdout-path = _1;
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   mfc_left: region@7700 {
+   compatible = "shared-dma-pool";
+   reusable;
+   reg = <0x7700 0x100>;
+   };
+
+   mfc_right: region@7800 {
+   compatible = "shared-dma-pool";
+   reusable;
+   reg = <0x7800 0x100>;
+   };
+   };
+
firmware@0204F000 {
compatible = "samsung,secure-firmware";
reg = <0x0204F000 0x1000>;
@@ -447,6 +465,12 @@
clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
 };
 
+ {
+   memory-region = <_left>, <_right>;
+   memory-region-names = "left", "right";
+   status = "okay";
+};
+
  {
status = "okay";
 };
-- 
1.9.2

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


Re: [RFC PATCH v3 0/2] Expose DMA_MEMORY_EXCLUSIVE through shared-dma-pool

2015-11-13 Thread Marek Szyprowski

Hello,

On 2015-11-10 17:18, Neil Armstrong wrote:

The shared-dma-pool dt node only exposes exclusive memory, but in order to 
export
non-exclusive coherent memory, add the no-exclusive property and document it.

v3: use correct of_get_flat_dt_prop helper
v2: simplify patch by looking for DT attribute in callback

Neil Armstrong (2):
   base: dma-coherent: Add DT property for non exclusive shared-dma-pool
   devicetree: reserved-memory: document the optional no-exclusive parameter

  .../devicetree/bindings/reserved-memory/reserved-memory.txt | 3 +++
  drivers/base/dma-coherent.c | 6 +-
  2 files changed, 8 insertions(+), 1 deletion(-)



Acked-by: Marek Szyprowski <m.szyprow...@samsung.com>

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

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


Re: [PATCH 1/1] drivers: of: of_reserved_mem: fixup the alignment with CMA setup

2015-11-10 Thread Marek Szyprowski

Hello,

On 2015-11-10 13:30, Jason Liu wrote:

There is an alignment mismatch issue between the of_reserved_mem and
the CMA setup requirement. The of_reserved_mem will try to get the
alignment value from the DTS and pass it to __memblock_alloc_base to
do the memory block base allocation, but the alignment value specified
in the DTS may not satisfy the CAM setup requirement since CMA setup
required the alignment as the following in the code:

align = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);

The sanity check in the function of rmem_cma_setup will fail if the
alignment does not setup correctly and thus CMA will fail to setup.

This patch is to fixup the alignment to meet the CMA setup required.

Mailing-list-thread: https://lkml.org/lkml/2015/11/9/138
Signed-off-by: Jason Liu <r64...@freescale.com>
Cc: Marek Szyprowski <m.szyprow...@samsung.com>
Cc: Grant Likely <grant.lik...@linaro.org>
Cc: Rob Herring <robh...@kernel.org>


Acked-by: Marek Szyprowski <m.szyprow...@samsung.com>


---
  drivers/of/of_reserved_mem.c | 4 
  1 file changed, 4 insertions(+)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 62f467b..9394311 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -124,6 +124,10 @@ static int __init __reserved_mem_alloc_size(unsigned long 
node,
align = dt_mem_next_cell(dt_root_addr_cells, );
}
  
+	/* Need adjust the alignment to satisfy the CMA requirement */

+   if (IS_ENABLED(CONFIG_CMA) && of_flat_dt_is_compatible(node, 
"shared-dma-pool"))
+   align = max(align, (phys_addr_t)PAGE_SIZE << max(MAX_ORDER - 1, 
pageblock_order));
+
prop = of_get_flat_dt_prop(node, "alloc-ranges", );
if (prop) {
  


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

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


Re: [PATCH 01/10] clk/samsung: exynos5433: add definitions of HDMI-PHY output clocks

2015-10-20 Thread Marek Szyprowski

Hello,

On 2015-10-20 12:34, Michael Turquette wrote:

Quoting Andrzej Hajda (2015-10-20 02:22:32)

HDMI driver must re-parent respective muxes during HDMI-PHY on/off
to HDMI-PHY output clocks. To reference those clocks their
definitions should be added.

Signed-off-by: Andrzej Hajda <a.ha...@samsung.com>
---
  drivers/clk/samsung/clk-exynos5433.c   | 6 --
  include/dt-bindings/clock/exynos5433.h | 5 -
  2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos5433.c 
b/drivers/clk/samsung/clk-exynos5433.c
index 650ec13..e037406 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -2614,8 +2614,10 @@ static struct samsung_fixed_rate_clock disp_fixed_clks[] 
__initdata = {
 FRATE(0, "phyclk_mipidphy0_rxclkesc0_phy", NULL, CLK_IS_ROOT,
 1),
 /* PHY clocks from HDMI_PHY */
-   FRATE(0, "phyclk_hdmiphy_tmds_clko_phy", NULL, CLK_IS_ROOT, 3),
-   FRATE(0, "phyclk_hdmiphy_pixel_clko_phy", NULL, CLK_IS_ROOT, 16600),
+   FRATE(CLK_PHYCLK_HDMIPHY_TMDS_CLKO_PHY, "phyclk_hdmiphy_tmds_clko_phy",
+   NULL, CLK_IS_ROOT, 3),
+   FRATE(CLK_PHYCLK_HDMIPHY_PIXEL_CLKO_PHY, 
"phyclk_hdmiphy_pixel_clko_phy",
+   NULL, CLK_IS_ROOT, 16600),
  };
  
  static struct samsung_mux_clock disp_mux_clks[] __initdata = {

diff --git a/include/dt-bindings/clock/exynos5433.h 
b/include/dt-bindings/clock/exynos5433.h
index 5bd80d5..4f0d566 100644
--- a/include/dt-bindings/clock/exynos5433.h
+++ b/include/dt-bindings/clock/exynos5433.h
@@ -765,7 +765,10 @@
  #define CLK_SCLK_RGB_VCLK  109
  #define CLK_SCLK_RGB_TV_VCLK   110
  
-#define DISP_NR_CLK111

+#define CLK_PHYCLK_HDMIPHY_PIXEL_CLKO_PHY  111
+#define CLK_PHYCLK_HDMIPHY_TMDS_CLKO_PHY   112
+
+#define DISP_NR_CLK113

Why break compatibility with older DTBs?


This patch just adds support for 2 more clocks to exynos 5433 clk driver,
which were previously undefined. How this break compatibility with older 
DTBs?


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

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


Re: [RFT 0/3] usb: usb3503: Fix probing on Arndale board (missing phy)

2015-10-08 Thread Marek Szyprowski

Hello,

On 2015-10-08 11:35, Javier Martinez Canillas wrote:

Hello,

On 10/08/2015 08:23 AM, Marek Szyprowski wrote:

Hello,

On 2015-10-08 08:02, Krzysztof Kozlowski wrote:

On 07.10.2015 23:26, Marek Szyprowski wrote:

Hello,

On 2015-10-07 02:30, Krzysztof Kozlowski wrote:

Introduction

This patchset tries to fix probing of usb3503 on Arndale board
if the Samsung PHY driver is probed later (or built as a module).

*The patchset was not tested on Arndale board.*
I don't have that board. Please test it and say if the usb3503
deferred probe
works fine and the issue is solved.

The patchset was tested on Odroid U3 board (which is different!)
in a simulated environment. It is not sufficient testing.


Difference
==
The usb3503 device driver can be used as a I2C device (on Odroid U3)
or as a platform device connected through phy (on Arndale). In the second
case the necessary phy reference has to be obtained and enabled.

For some details please look also at thread [0][1].

[0]
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/348524.html

[1]
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/348875.html



I'm not sure that this is the correct approach. usb3503 chip is simply
connected
to Exynos USB2 phy, so it visible on the USB bus. The real driver that
controls USB2
PHY is Exynos EHCI driver and USB3503 should not mess around it.

The ehci node (usb@1211) has one port configured and it takes one
PHY reference (phy of id 1 - USB host). I can't see driver taking
reference to HSIC0 or HSIC1 phys... Since I cannot diagnose the error I
don't know what is really expected here.

It looks that EHCI in Exynos 5250 and 5420 still use old phy bindings. For
the reference, see Exynos4 dts and exynos4412-odroidu3.dts to check how to 
enable
more than one USB port (Odroid U3 has both HSIC ports enabled).


In my opinion all that is needed in case of Arndale board is forcing
reset of
usb3503 chip after successful EHCI and USB2 PHY initialization (for some
reason
initialization of usb3503 chip must be done after usb host initialization).
However I have no idea which driver should trigger this reset. Right now
I didn't
find any good solution for additional control for devices which are on
autoprobed
bus like usb.

The reset is done at the end of usb3503's probe. The question "why
usb3503 has to be initialized after EHCI and USB PHY" is still valid...

I remember that I saw some code to reset HSIC device after phy power on in case
of HSIC-connected modem chip, so maybe this is somehow common for HSIC chips
(which are some special case of 'embedded usb').


I also don't have an Arndale board and haven't followed the thread to closely
but I just wanted to mention that the ChromiumOS 3.8 tree has a workaround to
reset the HSIC phys:

https://chromium.googlesource.com/chromiumos/third_party/kernel/+/81685c447954a29d1098268776582457258dd98f%5E%21/

and later a "supports-hsicphy-reset" DT property was added to force the reset
per board instead of unconditionally:

https://chromium.googlesource.com/chromiumos/third_party/kernel/+/a4d1c1a223ffa1ed38a4257d0378ca70c6667be0%5E%21/


I didn't check this approach, but for me it looks that the problem is caused
by the lack of resetting the chip connected to hsic phy not the lack of
resetting the phy itself. However this is pure speculation and one should
check it with the real hardware.

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

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


Re: [RFT 0/3] usb: usb3503: Fix probing on Arndale board (missing phy)

2015-10-07 Thread Marek Szyprowski

Hello,

On 2015-10-07 02:30, Krzysztof Kozlowski wrote:

Introduction

This patchset tries to fix probing of usb3503 on Arndale board
if the Samsung PHY driver is probed later (or built as a module).

*The patchset was not tested on Arndale board.*
I don't have that board. Please test it and say if the usb3503 deferred probe
works fine and the issue is solved.

The patchset was tested on Odroid U3 board (which is different!)
in a simulated environment. It is not sufficient testing.


Difference
==
The usb3503 device driver can be used as a I2C device (on Odroid U3)
or as a platform device connected through phy (on Arndale). In the second
case the necessary phy reference has to be obtained and enabled.

For some details please look also at thread [0][1].

[0] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/348524.html
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/348875.html



I'm not sure that this is the correct approach. usb3503 chip is simply 
connected
to Exynos USB2 phy, so it visible on the USB bus. The real driver that 
controls USB2

PHY is Exynos EHCI driver and USB3503 should not mess around it.

In my opinion all that is needed in case of Arndale board is forcing 
reset of
usb3503 chip after successful EHCI and USB2 PHY initialization (for some 
reason

initialization of usb3503 chip must be done after usb host initialization).
However I have no idea which driver should trigger this reset. Right now 
I didn't
find any good solution for additional control for devices which are on 
autoprobed

bus like usb.

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

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


Re: [PATCH v2] ARM: dts: exynos5420: fix wrong clock binding for sysmmu_fimd1_1

2015-09-23 Thread Marek Szyprowski

Hello,

On 2015-09-23 09:41, Joonyoung Shim wrote:

The sysmmu_fimd1_1 should bind the clock CLK_SMMU_FIMD1M1, not the clock
CLK_SMMU_FIMD1M0. CLK_SMMU_FIMD1M0 is a clock for the sysmmu_fimd1_0.

This wrong clock binding causes the problem that is blocked in iommu_map
function when IOMMU is enabled and exynos-drm driver tries to allocate
buffer via DMA mapping API on Odroid-XU3 board.

Fixes: b70045167815 ("ARM: dts: add sysmmu nodes for exynos5420")
Signed-off-by: Joonyoung Shim <jy0922.s...@samsung.com>
Cc: <sta...@vger.kernel.org> # v4.2
Reviewed-by: Javier Martinez Canillas <jav...@osg.samsung.com>


Acked-by: Marek Szyprowski <m.szyprow...@samsung.com>


---
Changes for v2:
- Update the commit message
- Add Fixes: and Reviewed-by: tags

  arch/arm/boot/dts/exynos5420.dtsi | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos5420.dtsi 
b/arch/arm/boot/dts/exynos5420.dtsi
index df9aee9..1b3d6c7 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -1117,7 +1117,7 @@
interrupt-parent = <>;
interrupts = <3 0>;
clock-names = "sysmmu", "master";
-   clocks = < CLK_SMMU_FIMD1M0>, < CLK_FIMD1>;
+   clocks = < CLK_SMMU_FIMD1M1>, < CLK_FIMD1>;
    power-domains = <_pd>;
#iommu-cells = <0>;
};


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

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


Re: [PATCH/RFC 0/4] Probe deferral for IOMMU DT integration

2015-03-04 Thread Marek Szyprowski
 as 3.b, leading to infinite probe deferral of bus master devices.

For those reasons we have concluded that IOMMU probe deferral needs to be
implemented with a combination of several mechanisms. The following steps
should happen at bus master device probe time.

1. The IOMMU device referenced by the firmware with the bus master device is
looked up. On DT-based systems, this will be the IOMMU DT node referenced by
the iommus property. If no IOMMU device is associated, dma_map_ops will be set
to linear mapping or SWIOTLB and device probe will continue.

2. An IOMMU device is referenced for the bus master device.

The corresponding IOMMU instance is looked up. This requires a new IOMMU
registration system. IOMMU drivers will create IOMMU instances at probe time
and register them with the IOMMU core.

If an IOMMU instance is found for the referenced IOMMU device, the IOMMU
instance's of_xlate function will be called to setup the IOMMU.

If the of_xlate call succeeds dma_map_ops will be set to IOMMU ops and device
probe will continue. If the call fails we can either fail the bus master
device probe, or fall back to non-IOMMU dma_map_ops (to be discussed).

3. The IOMMU device referenced for the bus master device isn't present, due to
the IOMMU device probe not having been performed yet, having been deferred, or
having failed.

The IOMMU driver associated with the IOMMU device is looked up. This was
initially thought to require an early registration mechanism for IOMMU drivers
(using an OF_DECLARE mechanism for DT-based systems for instance), but on
second thought it might be possible to implement this based on normal driver
registration (to be researched).

If an IOMMU driver is found for the referenced IOMMU device, a callback
function of the IOMMU driver is called to check whether an IOMMU instance is
expected to be registered later (most IOMMU drivers will just return true, so
we could skip this callback function until an IOMMU driver requires it). If an
IOMMU instance is expected to be registered later the bus master device probe
is deferred. Otherwise dma_map_ops will be set to linear mapping/SWIOTLB and
device probe will continue.


The initial DMA mask and the DMA offset can still be configured at device
instantiation time if desired.


I'm sorry for not participating in the discussions, I was terribly busy 
with our
internal stuff. The approach you have described looks fine although I 
would like
also to know a bit more about the roadmap of development. The IOMMU 
integration

is being discussed for over 2 years and right now we are STILL discussing.

Do you plan to post any patches implementing this approach? I would 
really like
to merge something simple, maybe not fully optimized and then resolve 
all the

corner cases and possible integration details.




- Currently tested where we knew the driver was going to be deferring.
Probably need some logic for calling of_dma_configure again.

This is based on Robin Murphy's work for dma mapping[4] and a few
patches from Murali Kaicheri[5] for of_dma_configure.


[1]
http://lists.linuxfoundation.org/pipermail/iommu/2015-January/011764.html
[2]
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-August/279036.ht
ml [3]
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-December/311579.
html [4]
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/315459.h
tml [5]
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/319390.h
tml

Laura Abbott (3):
   dma-mapping: Make arch_setup_dma_ops return an error code
   of: Return error codes from of_dma_configure
   iommu/arm-smmu: Support deferred probing

Mitchel Humpherys (1):
   iommu/arm-smmu: add support for specifying clocks

  arch/arm/include/asm/dma-mapping.h   |   2 +-
  arch/arm/mm/dma-mapping.c|   4 +-
  arch/arm64/include/asm/dma-mapping.h |   2 +-
  arch/arm64/mm/dma-mapping.c  |  16 +--
  drivers/iommu/arm-smmu.c | 186 ++--
  drivers/iommu/iommu.c|  49 -
  drivers/iommu/of_iommu.c |  14 ++-
  drivers/of/device.c  |   9 +-
  include/linux/dma-mapping.h  |   7 +-
  include/linux/iommu.h|   2 +
  include/linux/of_device.h|   4 +-
  11 files changed, 268 insertions(+), 27 deletions(-)


Best regards
--
Marek Szyprowski, PhD
Samsung RD Institute Poland

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


Re: [PATCH/RFC 0/4] Probe deferral for IOMMU DT integration

2015-02-11 Thread Marek Szyprowski

Hello,

On 2015-02-07 23:41, a...@arndb.de wrote:

Laura Abbott lau...@codeaurora.org hat am 6. Februar 2015 um 01:31
geschrieben:

The requirement for this is based on a previous patch to add clock
support to the ARM SMMU driver[2]. Once we have clock support, it's
possible that the driver itself may need to be defered which breaks
a bunch of assumptions about how SMMU probing is supposed to work.
  
Hi Laura,
  
I was hoping that we would not need this, and instead treat the iommu in

the same way as timers and SMP initialization, both
of which need to be run early at boot time but may rely on clock controllers
to be initialized first.
  
Is there a specific requirement that makes this impossible here, or is your

intention to solve the problem more nicely by allowing deferred probing
over forcing the input clocks of the iommu to be early?


I case of Exynos SoCs there is also a dependency on power domains (some 
might

be disabled by the bootloader). It is convenient to use the whole device
infrastructure for this although it still doesn't provide any methods of
modelling the real power management dependencies. Right now I simply ignored
this problem and left it for the future.

I will check if this patchset helps in our case.

Best regards
--
Marek Szyprowski, PhD
Samsung RD Institute Poland

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


Re: [PATCH 1/4] mmc: core: add support for hardware reset gpio line

2015-01-30 Thread Marek Szyprowski

Hello,

On 2015-01-29 11:56, Javier Martinez Canillas wrote:

On Thu, Jan 29, 2015 at 10:15 AM, Marek Szyprowski
m.szyprow...@samsung.com wrote:

Also, I wonder whether we could extend the mmc-pwrseq to cover your
case? Did you consider that as an option?


I didn't consider mmc-pwrseq yet. For me it looked straightforward to

I agree with Ulf that using mmc-pwrseq would be a good solution and in
fact I think the pwrseq_simple [0] driver will fit your use case since
it supports a reset GPIO pin which is what many WLAN chips attached to
a SDIO interface use.


Ok, I've checked mmc-prwseq and mmc-pwrseq-simple. I also checked the
hardware and it mmc-pwrseq-simple cannot be used directly.

Although the signal is called RSTN (on Odroid U3 schema), the eMMC card
gets resetted not on low line level, but during the rising edge. This RSTN
line is also pulled up by the external resistor. However, the strangest
thing is the fact that the default SoC configuration (which is applied
during hw reset) for this GPIO line is input, pulled-down. The SoC
internal pull-down is stronger than the external pull up, so in the end,
during the SoC reboot the RSTN signal is set to zero. Later bootloader
disables the internal pull-down.

To sum up - to perform proper reboot on Odroid U3/XU3, one need to set
RSTN to zero, wait a while and the set it back to 1.

To achieve this with mmc-pwrseq-simple, I would need to modify the power_off
callback to toggle reset line to zero and back to one. This however might
not be desired to other sd/mmc cards used with mmc-pwrseq-simple.

I can also provide separate mmc-pwrsrq-odroid driver, which will be very
similar to mmc-pwrseq-simple.

Ulf - which approach would you prefer?





implement
it just like card detect or write-protection gpio pins. I already noticed
that
there is code for some mmc host driver, which perform mmc hardware reset. If
you
think that extending pwrseq is the better approach, I will try to update my
patches. This will add reboot handler to mmc-pwrseq then. The only question
is

I don't think that adding a reboot handler to mmc-pwrseq is needed.
AFAICT the call chain is:

sys_reboot() - kernel_restart() - device_shutdown() -
mmc_bus_shutdown() - _mmc_suspend() - mmc_power_off() -
mmc_pwrseq_power_off() - struct mmc_pwrseq_ops .power_off

So since the pwrseq_simple already asserts the reset GPIO in
.power_off, it should be enough to ensure the eMMC will be reset to
its default configuration for the iROM to work properly.

It also asserts the GPIO pin in .pre_power_on and de-asserts in
.post_power_on which should be needed as well for the other case you
mentioned when a broken bootloader left the emmc card in some unknown
state.


emergency_restart() doesn't call device_shutdown(), so I think it still 
makes

sense to add real reset handler to mmc-pwrseq to ensure that power_off will
be called even during emergency_restart().

Best regards
--
Marek Szyprowski, PhD
Samsung RD Institute Poland

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


Re: [PATCH 1/4] mmc: core: add support for hardware reset gpio line

2015-01-29 Thread Marek Szyprowski

Hello,

On 2015-01-28 15:24, Ulf Hansson wrote:

On 28 January 2015 at 14:59, Marek Szyprowski m.szyprow...@samsung.com wrote:

There are boards (like Hardkernel's Odroid boards) on which eMMC card's
reset line is connected to GPIO line instead of the hardware reset
logic. In case of such boards, if first stage of bootloader is loaded
from such eMMC card, before performing system reboot, additional reset
of eMMC card is required to properly boot the whole system again. This
patch adds code for handling reset gpio lines defined in device tree.


I don't follow the above sequence. Can you try to elaborate and
describe for what exact scenario we require the hardware reset to be
done?


Odroid boards uses multi stage bootloaders. The very first stage is in 
SoC ROM.
That code loads next stages (called bl1, bl2, tz) from either eMMC or SD 
card
(depending on jumper configuration or some card detect pins). This ROM 
code is

very simple and assumes that the mmc card has been reset to the default
configuration. However, eMMC card is not being reset by the board 
'reboot' logic.
Instead the nreset line from emmc card is connected to gpio line of SoC. 
Thus to
perform full system reboot procedure, before triggering reboot inside 
the SoC,
one need to manually toggle nreset line of this emmc card to 'zero' for 
a while.
Only then the card is put back to the default state, so ROM code is able 
to read

bootloaders from it.

My patch adds code for managing gpio line connected to nreset signal of 
emmc card.
It registers reset handler, which is being triggered from Linux reboot 
code. This
handler toggles such gpio line before the final reboot is triggered. My 
patch also
provides a function for registering as a mmc host hw_reset callback, so 
it can be
used to reset mmc card before initializing it with kernel driver (this 
is already
implemented), which also might help to get it working if broken 
bootloader left
the emmc card in some unknown/broken state (already observed such issue, 
but it

has been fixed finally by patching bootloader).



Also, I wonder whether we could extend the mmc-pwrseq to cover your
case? Did you consider that as an option?


I didn't consider mmc-pwrseq yet. For me it looked straightforward to 
implement
it just like card detect or write-protection gpio pins. I already 
noticed that
there is code for some mmc host driver, which perform mmc hardware 
reset. If you

think that extending pwrseq is the better approach, I will try to update my
patches. This will add reboot handler to mmc-pwrseq then. The only 
question is

weather to use it always when mmc-pwrseq has been enabled or only if some
additional property like 'reset-on-reboot' has been provided.

Best regards
--
Marek Szyprowski, PhD
Samsung RD Institute Poland

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


Re: [PATCH 1/4] mmc: core: add support for hardware reset gpio line

2015-01-29 Thread Marek Szyprowski

Hello,

On 2015-01-29 11:56, Javier Martinez Canillas wrote:

On Thu, Jan 29, 2015 at 10:15 AM, Marek Szyprowski
m.szyprow...@samsung.com wrote:

Also, I wonder whether we could extend the mmc-pwrseq to cover your
case? Did you consider that as an option?

I didn't consider mmc-pwrseq yet. For me it looked straightforward to

I agree with Ulf that using mmc-pwrseq would be a good solution and in
fact I think the pwrseq_simple [0] driver will fit your use case since
it supports a reset GPIO pin which is what many WLAN chips attached to
a SDIO interface use.

implement
it just like card detect or write-protection gpio pins. I already noticed
that
there is code for some mmc host driver, which perform mmc hardware reset. If
you
think that extending pwrseq is the better approach, I will try to update my
patches. This will add reboot handler to mmc-pwrseq then. The only question
is

I don't think that adding a reboot handler to mmc-pwrseq is needed.
AFAICT the call chain is:

sys_reboot() - kernel_restart() - device_shutdown() -
mmc_bus_shutdown() - _mmc_suspend() - mmc_power_off() -
mmc_pwrseq_power_off() - struct mmc_pwrseq_ops .power_off

So since the pwrseq_simple already asserts the reset GPIO in
.power_off, it should be enough to ensure the eMMC will be reset to
its default configuration for the iROM to work properly.


I think that I had to add reset handler, because device_shutdown() was not
called if reset was triggered from magic sysrq, but I will check it again.


It also asserts the GPIO pin in .pre_power_on and de-asserts in
.post_power_on which should be needed as well for the other case you
mentioned when a broken bootloader left the emmc card in some unknown
state.


weather to use it always when mmc-pwrseq has been enabled or only if some
additional property like 'reset-on-reboot' has been provided.


Having a reset GPIO is optional AFAIK so I don't think there is a need
for an additional reset-on-reboot propery.


Best regards
--
Marek Szyprowski, PhD
Samsung RD Institute Poland


Best regards,
Javier

[0]:
FYI, these are the relevant commits in linux-next:
fe1922d5d4d0 mmc: pwrseq_simple: Add support for a reset GPIO pin
ec2017f2491f mmc: pwrseq: Initial support for the simple MMC power
sequence provider
fe1686658f9c mmc: pwrseq: Document DT bindings for the simple MMC power sequence
1b745e8a4627 mmc: core: Initial support for MMC power sequences


Ok, I will check it.

Best regards
--
Marek Szyprowski, PhD
Samsung RD Institute Poland

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


[PATCH 4/4] ARM: dts: exynos5422-odroidxu3: add eMMC reset line

2015-01-28 Thread Marek Szyprowski
This patch adds reset-gpios property to the eMMC slot, so the MMC driver
is able to properly reset eMMC card on system restart and thus fixes
system hang on software reboot.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 arch/arm/boot/dts/exynos5422-odroidxu3.dts | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts 
b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
index a519c863248d..bafbc4e19adc 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
@@ -298,13 +298,15 @@
 
 mmc_0 {
status = okay;
+   reset-gpios = gpd1 0 0;
+   reset-invered;
broken-cd;
card-detect-delay = 200;
samsung,dw-mshc-ciu-div = 3;
samsung,dw-mshc-sdr-timing = 0 4;
samsung,dw-mshc-ddr-timing = 0 2;
pinctrl-names = default;
-   pinctrl-0 = sd0_clk sd0_cmd sd0_bus4 sd0_bus8;
+   pinctrl-0 = sd0_clk sd0_cmd sd0_bus4 sd0_bus8 emmc_nrst;
bus-width = 8;
cap-mmc-highspeed;
 };
@@ -330,6 +332,15 @@
};
 };
 
+pinctrl_1 {
+   emmc_nrst: emmc-nrst {
+   samsung,pins = gpd1-0;
+   samsung,pin-function = 0;
+   samsung,pin-pud = 0;
+   samsung,pin-drv = 0;
+   };
+};
+
 usbdrd_dwc3_0 {
dr_mode = host;
 };
-- 
1.9.2

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


[PATCH 1/2] mmc: dw_mmc-exynos: add support for controlling emmc reset pin

2015-01-27 Thread Marek Szyprowski
There are boards (like Hardkernel's Odroid boards) on which eMMC card's
reset line is connected to SoC GPIO line instead of the hardware reset
logic. In case of such boards, before performing system reboot,
additional reset of eMMC card is required to boot again properly.
This patch adds code for handling such cases.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 .../devicetree/bindings/mmc/exynos-dw-mshc.txt |  6 +++
 drivers/mmc/host/dw_mmc-exynos.c   | 43 +-
 2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt 
b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
index ee4fc0576c7d..fc53d335e7db 100644
--- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
@@ -50,6 +50,12 @@ Required Properties:
   - if CIU clock divider value is 0 (that is divide by 1), both tx and rx
 phase shift clocks should be 0.
 
+Optional properties:
+
+* dw-mshc-reset-gpios: optional property specifying gpio for the eMMC nreset
+  line, it will be triggered on system reboot to properly reset eMMC card for
+  next system boot.
+
 Required properties for a slot (Deprecated - Recommend to use one slot per 
host):
 
 * gpios: specifies a list of gpios used for command, clock and data bus. The
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
index 509365cb22c6..2add5a93859d 100644
--- a/drivers/mmc/host/dw_mmc-exynos.c
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -12,12 +12,14 @@
 #include linux/module.h
 #include linux/platform_device.h
 #include linux/clk.h
+#include linux/delay.h
 #include linux/mmc/host.h
 #include linux/mmc/dw_mmc.h
 #include linux/mmc/mmc.h
 #include linux/of.h
 #include linux/of_gpio.h
 #include linux/slab.h
+#include linux/reboot.h
 
 #include dw_mmc.h
 #include dw_mmc-pltfm.h
@@ -77,8 +79,23 @@ struct dw_mci_exynos_priv_data {
u32 sdr_timing;
u32 ddr_timing;
u32 cur_speed;
+   struct gpio_desc*reset_gpio;
+   struct notifier_block   reset_nb;
 };
 
+static int dw_mci_restart_handler(struct notifier_block *this,
+ unsigned long mode, void *cmd)
+{
+   struct dw_mci_exynos_priv_data *data;
+   data = container_of(this, struct dw_mci_exynos_priv_data, reset_nb);
+
+   gpiod_direction_output(data-reset_gpio, 0);
+   mdelay(150);
+   gpiod_direction_output(data-reset_gpio, 1);
+
+   return NOTIFY_DONE;
+}
+
 static struct dw_mci_exynos_compatible {
char*compatible;
enum dw_mci_exynos_type ctrl_type;
@@ -295,7 +312,20 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host)
return ret;
 
priv-ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div);
+
+   priv-reset_gpio = devm_gpiod_get_optional(host-dev,
+  samsung,dw-mshc-reset,
+  GPIOD_OUT_HIGH);
+   if (!IS_ERR_OR_NULL(priv-reset_gpio)) {
+   priv-reset_nb.notifier_call = dw_mci_restart_handler;
+   priv-reset_nb.priority = 255;
+   ret = register_restart_handler(priv-reset_nb);
+   if (ret)
+   dev_err(host-dev, cannot register restart handler\n);
+   }
+
host-priv = priv;
+
return 0;
 }
 
@@ -490,6 +520,17 @@ static int dw_mci_exynos_probe(struct platform_device 
*pdev)
return dw_mci_pltfm_register(pdev, drv_data);
 }
 
+static int dw_mci_exynos_remove(struct platform_device *pdev)
+{
+   struct dw_mci *host = platform_get_drvdata(pdev);
+   struct dw_mci_exynos_priv_data *priv = host-priv;
+
+   if (priv-reset_gpio)
+   unregister_restart_handler(priv-reset_nb);
+
+   return dw_mci_pltfm_remove(pdev);
+}
+
 static const struct dev_pm_ops dw_mci_exynos_pmops = {
SET_SYSTEM_SLEEP_PM_OPS(dw_mci_exynos_suspend, dw_mci_exynos_resume)
.resume_noirq = dw_mci_exynos_resume_noirq,
@@ -499,7 +540,7 @@ static const struct dev_pm_ops dw_mci_exynos_pmops = {
 
 static struct platform_driver dw_mci_exynos_pltfm_driver = {
.probe  = dw_mci_exynos_probe,
-   .remove = __exit_p(dw_mci_pltfm_remove),
+   .remove = dw_mci_exynos_remove,
.driver = {
.name   = dwmmc_exynos,
.of_match_table = dw_mci_exynos_match,
-- 
1.9.2

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


[PATCH 0/2] Fix reboot issue on Odroid boards with eMMC card

2015-01-27 Thread Marek Szyprowski
Hello,

This patchset fixes reboot hang issue on Hardkernel's Odroid boards with
eMMC card. Those boards are designed in such a way, that the eMMC nreset
signal is routed to SoC GPIO line instead of the board reset logic. To
properly restard system, one need to set this line to zero before
performing reboot.

The initial patches consisted of a complete reset/power off driver, but
after further analysis, it turned out that only eMMC nreset line control
logic is specific for those boards. Everything else can be done by
generic Exynos code, so the code has been moved to Exynos DW MMC driver.

Best regards
Marek Szyprowski
Samsung RD Institute Poland


Changelog:

initial version:
http://thread.gmane.org/gmane.linux.power-management.general/51855/


Path summary:

Marek Szyprowski (2):
  mmc: dw_mmc-exynos: add support for controlling emmc reset pin
  ARM: dts: exynos*-odroid*: add eMMC reset line

 .../devicetree/bindings/mmc/exynos-dw-mshc.txt |  6 +++
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi|  1 +
 arch/arm/boot/dts/exynos5422-odroidxu3.dts |  1 +
 drivers/mmc/host/dw_mmc-exynos.c   | 43 +-
 4 files changed, 50 insertions(+), 1 deletion(-)

-- 
1.9.2

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


[PATCH 2/2] ARM: dts: exynos*-odroid*: add eMMC reset line

2015-01-27 Thread Marek Szyprowski
This patch add samsung,dw-mshc-reset-gpios property to the eMMC slot,
so Exynos DW MMC driver is able to properly reset eMMC card on system
restart and thus fixes hang on software reboot.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 1 +
 arch/arm/boot/dts/exynos5422-odroidxu3.dts  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi 
b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index 74e89cbfb00c..97df0ef81d1a 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -69,6 +69,7 @@
samsung,dw-mshc-ciu-div = 3;
samsung,dw-mshc-sdr-timing = 2 3;
samsung,dw-mshc-ddr-timing = 1 2;
+   samsung,dw-mshc-reset-gpios = gpk1 2 1;
bus-width = 8;
cap-mmc-highspeed;
};
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts 
b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
index d829e220eedb..20064e36a5be 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
@@ -336,6 +336,7 @@
samsung,dw-mshc-ciu-div = 3;
samsung,dw-mshc-sdr-timing = 0 4;
samsung,dw-mshc-ddr-timing = 0 2;
+   samsung,dw-mshc-reset-gpios = gpd1 0 0;
pinctrl-names = default;
pinctrl-0 = sd0_clk sd0_cmd sd0_bus4 sd0_bus8;
bus-width = 8;
-- 
1.9.2

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


Re: [PATCH 1/2] power: reset: add driver for Hardkernel's Odroid boards

2015-01-27 Thread Marek Szyprowski

Hello,

On 2015-01-25 15:32, Sebastian Reichel wrote:

On Fri, Jan 23, 2015 at 12:11:22PM +0100, Marek Szyprowski wrote:

Frankly, I analyzed this case once again and I came to conclusion
that there is no need to make a separate reset driver for Odroid
boards. There is nothing special, specific to whole board about
this gpio. It is rather a property of MMC host controller and eMMC
card that is connected to it. When only gpio toggling code is
moved to reset handler registered from mmc controller, the board
properly performs reboot with a generic exynos4 code.

OK, so I guess this will be fixed independently via mmc subsystem.


I've posted an updated patch.




The poweroff code in above driver is just a generic Exynos4 code,
so again there is no need to duplicate it.

OK. It seems there is a driver for that in arch/arm/mach-exynos.
Otherwise I would have suggest to create something like
syscon-reboot for shutdown.


By moving the code to mmc driver, the same approach can be used for other
Odroid boards (XU/XU3) and maybe even other boards which need manual
resetting of eMMC cards to properly perform reboot procedure.

I suggest to start a new thread for discussing this, which includes
linux-mmc. It might be interesting to provide some more details about
eMMC_nDET, since MMC already contain a reset signal (which seems to
be used according to the odroid schematics I found).


My fault. The documentation for this initial driver was incorrect. The 
reboot
fix has noting to eMMC_nDET signal. It should be eMMC nreset, which is 
routed

directly to SoC GPIO line with external pull-up resistor. I really have no
idea why I wrote eMMC_nDET instead of nreset.

Best regards
--
Marek Szyprowski, PhD
Samsung RD Institute Poland

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


Re: [PATCH 0/2] Fix reboot issue on Odroid boards with eMMC card

2015-01-27 Thread Marek Szyprowski

Hello,

On 2015-01-27 09:56, Sjoerd Simons wrote:

On Tue, 2015-01-27 at 09:11 +0100, Marek Szyprowski wrote:

This patchset fixes reboot hang issue on Hardkernel's Odroid boards with
eMMC card. Those boards are designed in such a way, that the eMMC nreset
signal is routed to SoC GPIO line instead of the board reset logic. To
properly restard system, one need to set this line to zero before
performing reboot.

The initial patches consisted of a complete reset/power off driver, but
after further analysis, it turned out that only eMMC nreset line control
logic is specific for those boards. Everything else can be done by
generic Exynos code, so the code has been moved to Exynos DW MMC driver.

This seems a general board design quirk, rather then an exynos specific
one. Potentially better to have this in the mmc core so it can be
re-used by non-exynos boards?

A very quick peek at the schematic for the hardkernel C1 (amlogic
based), shows that for that board the eMMC reset line is hooked up to an
SoC gpio line as well. (Although ofcourse, it may not need to be reset
before a warm restart depending on what the amlogic rom code does).


Random side-note, at least the samsung peach chromebooks are also hooked
up this way. But don't run into this issue as they load their initial
stages from flash rather then the eMMC.


Okay, I will try to move all the code to mmc core. I've also noticed that
sdhci-pci driver already implements hw_reset feature with gpio line, 
although

I cannot find any user of it (I cannot find any platform data provider for
sdhci-pci driver).

Best regards
--
Marek Szyprowski, PhD
Samsung RD Institute Poland

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


Re: [PATCH 1/2] power: reset: add driver for Hardkernel's Odroid boards

2015-01-23 Thread Marek Szyprowski

Hello,

On 2015-01-22 02:33, Joonyoung Shim wrote:

On 01/22/2015 10:06 AM, Sebastian Reichel wrote:

On Wed, Oct 29, 2014 at 02:13:28PM +0100, Marek Szyprowski wrote:

This patch adds a driver implementing correct reboot and poweroff
procedures for Exynos4412-based Hardkernel's Odroid X/X2/U2/U3/U3+
boards.

Sorry it took so long. I have a couple of small requests before
applying this (comments inline).


Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
  .../bindings/power/reset/odroid-reset.txt  |  18 
  drivers/power/reset/Kconfig|   6 ++
  drivers/power/reset/Makefile   |   1 +
  drivers/power/reset/odroid-reboot.c| 119 +
  4 files changed, 144 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/power/reset/odroid-reset.txt
  create mode 100644 drivers/power/reset/odroid-reboot.c

diff --git a/Documentation/devicetree/bindings/power/reset/odroid-reset.txt 
b/Documentation/devicetree/bindings/power/reset/odroid-reset.txt
new file mode 100644
index ..86471a463518
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/reset/odroid-reset.txt
@@ -0,0 +1,18 @@
+* Device tree bindings for Hardkernel's Exynos4412 based Odroid boards
+
+This node is intended to allow proper system reboot and power off of
+Odroid X/X2/U2/U3/U3+ boards with eMMC storage. Without this node, board
+hangs during standard reset procedure.
+
+Required properties:
+- compatible:  hardkernel,odroid-reboot
+- samsung,pmureg-phandle:  phandle to Exynos PMU node
+- reset-gpios: phandle and gpio-specifier to the GPIO pin
+   connected to the eMMC_nDET
+
+Example:
+odroid_reboot {
+   compatible = hardkernel,odroid-reboot;
+   samsung,pmureg-phandle = pmu_system_controller;
+   reset-gpio = gpk1 2 0;
+};
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index f65ff49bb275..f02b13d5344f 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -84,6 +84,12 @@ config POWER_RESET_LTC2952
  This driver supports an external powerdown trigger and board power
  down via the LTC2952. Bindings are made in the device tree.
  
+config POWER_RESET_ODROID

+   bool Hardkernel's Exynos4412 based Odroid reboot driver
+   depends on POWER_RESET  ARCH_EXYNOS

once the arm specific restart handler is gone you can add ||
COMPILE_TEST


+   help
+ Power off and restart support for Odroid boards.
+
  config POWER_RESET_QNAP
bool QNAP power-off driver
depends on OF_GPIO  PLAT_ORION
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index 76ce1c59469b..178ee86eb813 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
  obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
  obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
  obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o
+obj-$(CONFIG_POWER_RESET_ODROID) += odroid-reboot.o
  obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
  obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
  obj-$(CONFIG_POWER_RESET_SUN6I) += sun6i-reboot.o
diff --git a/drivers/power/reset/odroid-reboot.c 
b/drivers/power/reset/odroid-reboot.c
new file mode 100644
index ..823e93539220
--- /dev/null
+++ b/drivers/power/reset/odroid-reboot.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * 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 option) any later version.
+ */
+
+#include linux/delay.h
+#include linux/gpio.h
+#include linux/io.h
+#include linux/mfd/syscon.h
+#include linux/module.h
+#include linux/of_platform.h
+#include linux/of_gpio.h
+#include linux/reboot.h
+#include linux/regmap.h
+
+#include asm/system_misc.h
+
+#define PS_HOLD_CONTROL0x330C
+
+struct odroid_reboot_data {
+   struct device *dev;
+   int power_gpio;
+   struct regmap *reg_pmu;
+   void (*reboot_func)(enum reboot_mode mode, const char *cmd);
+};
+
+static struct odroid_reboot_data *reboot_data;
+
+static void odroid_reboot(enum reboot_mode mode, const char *cmd)
+{
+   local_irq_disable();
+
+   gpio_set_value(reboot_data-power_gpio, 0);
+   mdelay(150);
+   gpio_set_value(reboot_data-power_gpio, 1);
+
+   reboot_data-reboot_func(mode, cmd);
+

It is called do_kernel_restart() if arm_pm_restart is NULL from
machine_restart of arch/arm/kernel/process.c

How about this?

if (reboot_data-reboot_func)
reboot_data-reboot_func(mode, cmd);
else
do_kernel_restart(cmd);


Frankly, I analyzed this case once again and I came

[PATCH v3 1/7 RESEND] PM / Domains: Add a note about power domain subdomains

2015-01-14 Thread Marek Szyprowski
This patch adds a note on defining subdomains to generic PM domain
binding documentation to let power domain providers use common approach
for defining power domain hierarchy.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
RESEND version:
- fixed spelling mistakes, thanks go to Geert!
---
 .../devicetree/bindings/power/power_domain.txt | 29 ++
 1 file changed, 29 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/power_domain.txt 
b/Documentation/devicetree/bindings/power/power_domain.txt
index 98c1667..eeea45b 100644
--- a/Documentation/devicetree/bindings/power/power_domain.txt
+++ b/Documentation/devicetree/bindings/power/power_domain.txt
@@ -19,6 +19,16 @@ Required properties:
providing multiple PM domains (e.g. power controllers), but can be any value
as specified by device tree binding documentation of particular provider.
 
+Optional properties:
+ - power-domains : A phandle and PM domain specifier as defined by bindings of
+   the power controller specified by phandle.
+   Some power domains might be powered from another power domain (or have
+   other hardware specific dependencies). For representing such dependency
+   a standard PM domain consumer binding is used. When provided, all domains
+   created by the given provider should be subdomains of the domain
+   specified by this binding. More details about power domain specifier are
+   available in the next section.
+
 Example:
 
power: power-controller@1234 {
@@ -30,6 +40,25 @@ Example:
 The node above defines a power controller that is a PM domain provider and
 expects one cell as its phandle argument.
 
+Example 2:
+
+   parent: power-controller@1234 {
+   compatible = foo,power-controller;
+   reg = 0x1234 0x1000;
+   #power-domain-cells = 1;
+   };
+
+   child: power-controller@1234 {
+   compatible = foo,power-controller;
+   reg = 0x12341000 0x1000;
+   power-domains = parent 0;
+   #power-domain-cells = 1;
+   };
+
+The nodes above define two power controllers: 'parent' and 'child'.
+Domains created by the 'child' power controller are subdomains of '0' power
+domain provided by the 'parent' power controller.
+
 ==PM domain consumers==
 
 Required properties:
-- 
1.9.2

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


Re: [PATCH RFC v2 08/12] soc: samsung: pm_domain: Add support for parent power domain

2014-12-03 Thread Marek Szyprowski

Hello,

On 2014-11-25 10:19, Geert Uytterhoeven wrote:

On Tue, Nov 25, 2014 at 9:57 AM, amit daniel kachhap
amit.dan...@samsung.com  wrote:

diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt 
b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
index 00ebda1..0160bdc 100644
--- a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
+++ b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
@@ -24,6 +24,7 @@ Optional Properties:
 - pclkN, clkN: Pairs of parent of input clock and input clock to the
 devices in this power domain. Maximum of 4 pairs (N = 0 to 3)
 are supported currently.
+- parents: phandle of parent power domains.

Why not using just power-domains = pd_top?
This is consistent with how clocks refer to their parent clocks.


I agree. The only question is weather exynos dts should keep using 
samsung,power-domain
property, or switch to generic 'power-domains' approach. I assume that 
exynos-pm driver

should support both.


  Node of a device using power domains must have a samsung,power-domain property
  defined with a phandle to respective power domain.
@@ -48,6 +49,7 @@ Example:
 mfc_pd: power-domain@10044060 {
 compatible = samsung,exynos4210-pd, samsung,exynos7-pd-mfc;
 reg = 0x10044060 0x20;
+   parents = pd_top;
 #power-domain-cells = 0;
 };

This seems like a good and generic approach to describe that a PM
domain could have a parent. I would suggest to rename it, such it
reflects its a PM domain binding though.

I am not sure if this is generic. I guess PD's represented like below
are more generic.
PD1 {
 PD2 {
 PD3 {
 };
 };
};

Such a representation is not always possible.
If you have one power-controller for a hierarchy of PM domains, you can
use it.
If you have multiple power-controllers, the power controller nodes are at the
same level in DT, so you'll have to use power-domains properties to link
them together.


I agree. I will send updated patch for this purpose for existing exynos4 
power domain driver.


Best regards
--
Marek Szyprowski, PhD
Samsung RD Institute Poland

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


[PATCH 2/2] ARM: dts: exynos4412-odroid-common: add reboot handler

2014-10-29 Thread Marek Szyprowski
This patch adds node which enables board-specific reboot/poweroff code.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi 
b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index 4ebb5572d8d0..3544bb255e58 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -32,6 +32,12 @@
};
};
 
+   odroid_reboot {
+   compatible = hardkernel,odroid-reboot;
+   samsung,pmureg-phandle = pmu_system_controller;
+   reset-gpios = gpk1 2 0;
+   };
+
i2s0: i2s@0383 {
pinctrl-0 = i2s0_bus;
pinctrl-names = default;
-- 
1.9.2

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


[PATCH 1/2] power: reset: add driver for Hardkernel's Odroid boards

2014-10-29 Thread Marek Szyprowski
This patch adds a driver implementing correct reboot and poweroff
procedures for Exynos4412-based Hardkernel's Odroid X/X2/U2/U3/U3+
boards.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 .../bindings/power/reset/odroid-reset.txt  |  18 
 drivers/power/reset/Kconfig|   6 ++
 drivers/power/reset/Makefile   |   1 +
 drivers/power/reset/odroid-reboot.c| 119 +
 4 files changed, 144 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/power/reset/odroid-reset.txt
 create mode 100644 drivers/power/reset/odroid-reboot.c

diff --git a/Documentation/devicetree/bindings/power/reset/odroid-reset.txt 
b/Documentation/devicetree/bindings/power/reset/odroid-reset.txt
new file mode 100644
index ..86471a463518
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/reset/odroid-reset.txt
@@ -0,0 +1,18 @@
+* Device tree bindings for Hardkernel's Exynos4412 based Odroid boards
+
+This node is intended to allow proper system reboot and power off of
+Odroid X/X2/U2/U3/U3+ boards with eMMC storage. Without this node, board
+hangs during standard reset procedure.
+
+Required properties:
+- compatible:  hardkernel,odroid-reboot
+- samsung,pmureg-phandle:  phandle to Exynos PMU node
+- reset-gpios: phandle and gpio-specifier to the GPIO pin
+   connected to the eMMC_nDET
+
+Example:
+odroid_reboot {
+   compatible = hardkernel,odroid-reboot;
+   samsung,pmureg-phandle = pmu_system_controller;
+   reset-gpio = gpk1 2 0;
+};
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index f65ff49bb275..f02b13d5344f 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -84,6 +84,12 @@ config POWER_RESET_LTC2952
  This driver supports an external powerdown trigger and board power
  down via the LTC2952. Bindings are made in the device tree.
 
+config POWER_RESET_ODROID
+   bool Hardkernel's Exynos4412 based Odroid reboot driver
+   depends on POWER_RESET  ARCH_EXYNOS
+   help
+ Power off and restart support for Odroid boards.
+
 config POWER_RESET_QNAP
bool QNAP power-off driver
depends on OF_GPIO  PLAT_ORION
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index 76ce1c59469b..178ee86eb813 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
 obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
 obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
 obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o
+obj-$(CONFIG_POWER_RESET_ODROID) += odroid-reboot.o
 obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
 obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
 obj-$(CONFIG_POWER_RESET_SUN6I) += sun6i-reboot.o
diff --git a/drivers/power/reset/odroid-reboot.c 
b/drivers/power/reset/odroid-reboot.c
new file mode 100644
index ..823e93539220
--- /dev/null
+++ b/drivers/power/reset/odroid-reboot.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * 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 option) any later version.
+ */
+
+#include linux/delay.h
+#include linux/gpio.h
+#include linux/io.h
+#include linux/mfd/syscon.h
+#include linux/module.h
+#include linux/of_platform.h
+#include linux/of_gpio.h
+#include linux/reboot.h
+#include linux/regmap.h
+
+#include asm/system_misc.h
+
+#define PS_HOLD_CONTROL0x330C
+
+struct odroid_reboot_data {
+   struct device *dev;
+   int power_gpio;
+   struct regmap *reg_pmu;
+   void (*reboot_func)(enum reboot_mode mode, const char *cmd);
+};
+
+static struct odroid_reboot_data *reboot_data;
+
+static void odroid_reboot(enum reboot_mode mode, const char *cmd)
+{
+   local_irq_disable();
+
+   gpio_set_value(reboot_data-power_gpio, 0);
+   mdelay(150);
+   gpio_set_value(reboot_data-power_gpio, 1);
+
+   reboot_data-reboot_func(mode, cmd);
+
+   pr_emerg(%s: waiting for reboot\n, __func__);
+   while (1)
+   ;
+}
+
+static void odroid_power_off(void)
+{
+   regmap_update_bits(reboot_data-reg_pmu, PS_HOLD_CONTROL, 0x, 
0x5200);
+   while (1) {
+   pr_emerg(%s: should not reach here!\n, __func__);
+   msleep(1000);
+   }
+}
+
+static struct odroid_reboot_data *odroid_reboot_parse_dt(struct device *dev)
+{
+   struct device_node *np = dev-of_node;
+   struct odroid_reboot_data *data;
+
+   data = devm_kzalloc(dev, sizeof(struct odroid_reboot_data), GFP_KERNEL);
+   if (!data)
+   return NULL

Re: [PATCH v2 0/4] CMA device tree, once again

2014-08-26 Thread Marek Szyprowski

Hello,

On 2014-08-09 02:28, Laura Abbott wrote:

On 7/14/2014 12:12 AM, Marek Szyprowski wrote:

Hello,

This is one more respin of the patches which add support for creating
reserved memory regions defined in device tree. The last attempt
(http://lists.linaro.org/pipermail/linaro-mm-sig/2014-February/003738.html)
ended in merging only half of the code, so right now we have complete
documentation merged and only basic code, which implements a half of it
is written in the documentation. Although the merged patches allow to
reserve memory, there is no way of using it for devices and drivers.

This situation makes CMA rather useless, as the main architecture (ARM),
which used it, has been converted from board-file based system
initialization to device tree. Thus there is no place to use direct
calls to dma_declare_contiguous() and some new solution, which bases on
device tree, is urgently needed.

This patch series fixes this issue. It provides two, already widely
discussed and already present in the kernel, drivers for reserved
memory: first based on DMA-coherent allocator, second using Contiguous
Memory Allocator. The first one nicely implements typical 'carved out'
reserved memory way of allocating contiguous buffers in a kernel-style
way. The memory is used exclusively by devices assigned to the given
memory region. The second one allows to reuse reserved memory for
movable kernel pages (like disk buffers, anonymous memory) and migrates
it out when device to allocates contiguous memory buffer. Both driver
provides memory buffers via standard dma-mapping API.

The patches have been rebased on top of latest CMA and mm changes merged
to akmp kernel tree.

To define a 64MiB CMA region following node is needed:

multimedia_reserved: multimedia_mem_region {
compatible = shared-dma-pool;
reusable;
size = 0x400;
alignment = 0x40;
};

Similarly, one can define 64MiB region with DMA coherent memory:

multimedia_reserved: multimedia_mem_region {
compatible = shared-dma-pool;
no-map;
size = 0x400;
alignment = 0x40;
};


Longer term, I think it would be good if we didn't have to use no-map with
the coherent memory. With no-map and dma-coherent.c right now, not only
do you lose out on the physical memory space, you also have to give up
the same amount of vmalloc space for mapping. On arm32, if you have the default
240MB vmalloc space, 64M is ~25% of the vmalloc space. At least on arm you can
make this up by remapping the memory as coherent.

I haven't seen this picked up anywhere yet so you are welcome to add

Tested-by: Laura Abbott lau...@codeaurora.org


Right, when the code reaches mainline I will add code which will remove 
no-map

requirement. Changing memory attributes can be handled in this case the same
way as for CMA.

Best regards
--
Marek Szyprowski, PhD
Samsung RD Institute Poland

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


Re: [PATCH v2 RESEND 3/4] drivers: dma-coherent: add initialization from device tree

2014-07-30 Thread Marek Szyprowski

Hello,

On 2014-07-31 01:49, Grant Likely wrote:

On Tue, Jul 29, 2014 at 11:33 PM, Marek Szyprowski
m.szyprow...@samsung.com wrote:

Hello,


On 2014-07-29 23:54, Grant Likely wrote:

On Mon, 14 Jul 2014 10:28:06 +0200, Marek Szyprowski
m.szyprow...@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.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com

I think this looks okay. It isn't in my area of expertise though.
Comments below.


---
   drivers/base/dma-coherent.c | 137
++--
   1 file changed, 118 insertions(+), 19 deletions(-)

diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
index 7d6e84a51424..7185a4f247e1 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)

This is a bit odd. Why wouldn't you return the dma_mem pointer directly
instead of passing in a **mem argument?


Because this function (as a direct successor of dma_declare_coherent_memory)
doesn't
return typical error codes, but some custom values like DMA_MEMORY_MAP,
DMA_MEMORY_IO
or zero (which means failure). I wanted to avoid confusion with typical
error
handling path and IS_ERR/ERR_PTR usage used widely in other functions. This
probably
should be unified with the rest of kernel some day, but right now I wanted
to keep
the patch simple and easy to review.



   {
+   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

Re: [PATCH v2 RESEND 2/4] drivers: of: initialize and assign reserved memory to newly created devices

2014-07-29 Thread Marek Szyprowski

Hello,

On 2014-07-28 16:17, Grant Likely wrote:

On Mon, 14 Jul 2014 10:28:05 +0200, Marek Szyprowski m.szyprow...@samsung.com 
wrote:

Use recently introduced of_reserved_mem_device_init() function to
automatically assign respective reserved memory region to the newly created
platform and amba device.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com

I'm still not okay with this patch. I don't think it is appropriate to
add the hook into the generic path that gets used for every platform
device. The devices that need reserved memory should explicitly request
it, and any setup be done at that time.


Okay... I thought that it will be easier to have it done in generic 
code, if You don't
think so, then I give up and we will add it in all drivers requiring 
such memory regions.


What about patch 3/4 and 4/4? Would it be possible to have your ack to 
get them merged?
Right now patch 4/4 depends on changes from akpm tree, so it will be 
best to merge them

to akpm tree.

Best regards
--
Marek Szyprowski, PhD
Samsung RD Institute Poland

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


Re: [PATCH v2 RESEND 3/4] drivers: dma-coherent: add initialization from device tree

2014-07-29 Thread Marek Szyprowski

Hello,

On 2014-07-29 23:54, Grant Likely wrote:

On Mon, 14 Jul 2014 10:28:06 +0200, Marek Szyprowski m.szyprow...@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.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com

I think this looks okay. It isn't in my area of expertise though.
Comments below.


---
  drivers/base/dma-coherent.c | 137 ++--
  1 file changed, 118 insertions(+), 19 deletions(-)

diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
index 7d6e84a51424..7185a4f247e1 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)

This is a bit odd. Why wouldn't you return the dma_mem pointer directly
instead of passing in a **mem argument?


Because this function (as a direct successor of 
dma_declare_coherent_memory) doesn't
return typical error codes, but some custom values like DMA_MEMORY_MAP, 
DMA_MEMORY_IO
or zero (which means failure). I wanted to avoid confusion with typical 
error
handling path and IS_ERR/ERR_PTR usage used widely in other functions. 
This probably
should be unified with the rest of kernel some day, but right now I 
wanted to keep

the patch simple and easy to review.


  {
+   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

[PATCH v2 2/4] drivers: of: initialize and assign reserved memory to newly created devices

2014-07-14 Thread Marek Szyprowski
Use recently introduced of_reserved_mem_device_init() function to
automatically assign respective reserved memory region to the newly created
platform and amba device.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/of/platform.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 6c48d73a7fd7..a7f967866f13 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[] = {
@@ -237,12 +238,15 @@ 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
 */
 
if (of_device_add(dev) != 0) {
+   of_reserved_mem_device_release(dev-dev);
platform_device_put(dev);
goto err_clear_flag;
}
@@ -304,6 +308,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)
@@ -330,6 +336,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);
 err_clear_flag:
of_node_clear_flag(node, OF_POPULATED);
-- 
1.9.2

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


[PATCH v2 0/4] CMA device tree, once again

2014-07-14 Thread Marek Szyprowski
Hello,

This is one more respin of the patches which add support for creating
reserved memory regions defined in device tree. The last attempt
(http://lists.linaro.org/pipermail/linaro-mm-sig/2014-February/003738.html)
ended in merging only half of the code, so right now we have complete
documentation merged and only basic code, which implements a half of it
is written in the documentation. Although the merged patches allow to
reserve memory, there is no way of using it for devices and drivers.

This situation makes CMA rather useless, as the main architecture (ARM),
which used it, has been converted from board-file based system
initialization to device tree. Thus there is no place to use direct
calls to dma_declare_contiguous() and some new solution, which bases on
device tree, is urgently needed.

This patch series fixes this issue. It provides two, already widely
discussed and already present in the kernel, drivers for reserved
memory: first based on DMA-coherent allocator, second using Contiguous
Memory Allocator. The first one nicely implements typical 'carved out'
reserved memory way of allocating contiguous buffers in a kernel-style
way. The memory is used exclusively by devices assigned to the given
memory region. The second one allows to reuse reserved memory for
movable kernel pages (like disk buffers, anonymous memory) and migrates
it out when device to allocates contiguous memory buffer. Both driver
provides memory buffers via standard dma-mapping API.

The patches have been rebased on top of latest CMA and mm changes merged
to akmp kernel tree.

To define a 64MiB CMA region following node is needed:

multimedia_reserved: multimedia_mem_region {
compatible = shared-dma-pool;
reusable;
size = 0x400;
alignment = 0x40;
};

Similarly, one can define 64MiB region with DMA coherent memory:

multimedia_reserved: multimedia_mem_region {
compatible = shared-dma-pool;
no-map;
size = 0x400;
alignment = 0x40;
};

Then the defined region can be assigned to devices:

scaler: scaler@1250 {
memory-region = multimedia_reserved;
/* ... */
};
codec: codec@1260 {
memory-region = multimedia_reserved;
/* ... */
};

Best regards
Marek Szyprowski
Samsung RD Institute Poland

Changes since v1:
(http://www.spinics.net/lists/arm-kernel/msg343702.html)
- fixed possible memory leak in case of reserved memory allocation failure
  (thanks to Joonsoo Kim)

Changes since the version posted in '[PATCH v6 00/11] reserved-memory 
regions/CMA in devicetree, again' thread 
http://lists.linaro.org/pipermail/linaro-mm-sig/2014-February/003738.html:
- rebased on top of '[PATCH v3 -next 0/9] CMA: generalize CMA reserved
area management code' patch series on v3.16-rc3
- improved dma-coherent driver, now it correctly handles assigning more
than one device to the given memory region


Patch summary:

Marek Szyprowski (4):
  drivers: of: add automated assignment of reserved regions to client
devices
  drivers: of: initialize and assign reserved memory to newly created
devices
  drivers: dma-coherent: add initialization from device tree
  drivers: dma-contiguous: add initialization from device tree

 drivers/base/dma-coherent.c | 40 +++
 drivers/base/dma-contiguous.c   | 60 +++
 drivers/of/of_reserved_mem.c| 70 +
 drivers/of/platform.c   |  7 +
 include/linux/cma.h |  3 ++
 include/linux/of_reserved_mem.h |  7 +
 mm/cma.c| 62 +---
 7 files changed, 238 insertions(+), 11 deletions(-)

-- 
1.9.2

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


[PATCH v2 4/4] drivers: dma-contiguous: add initialization from device tree

2014-07-14 Thread Marek Szyprowski
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 jo...@codeaurora.org

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

diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 6606abdf880c..0e480146fe05 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -211,3 +211,63 @@ 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 void rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev)
+{
+   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)
+{
+   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 32cab7a425f9..9a18a2b1934c 100644
--- a/include/linux/cma.h
+++ b/include/linux/cma.h
@@ -16,6 +16,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 4b251b037e1b..b3d8b925ad34 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -140,6 +140,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

[PATCH v2 1/4] drivers: of: add automated assignment of reserved regions to client devices

2014-07-14 Thread Marek Szyprowski
This patch adds code for automated assignment of reserved memory regions
to struct device. reserved_mem-ops-device_init()/device_cleanup()
callbacks are called to perform reserved memory driver specific
initialization and cleanup

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/of/of_reserved_mem.c| 70 +
 include/linux/of_reserved_mem.h |  7 +
 2 files changed, 77 insertions(+)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 632aae861375..59fb12e84e6b 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -206,8 +206,16 @@ void __init fdt_init_reserved_mem(void)
for (i = 0; i  reserved_mem_count; i++) {
struct reserved_mem *rmem = reserved_mem[i];
unsigned long node = rmem-fdt_node;
+   int len;
+   const __be32 *prop;
int err = 0;
 
+   prop = of_get_flat_dt_prop(node, phandle, len);
+   if (!prop)
+   prop = of_get_flat_dt_prop(node, linux,phandle, len);
+   if (prop)
+   rmem-phandle = of_read_number(prop, len/4);
+
if (rmem-size == 0)
err = __reserved_mem_alloc_size(node, rmem-name,
 rmem-base, rmem-size);
@@ -215,3 +223,65 @@ void __init fdt_init_reserved_mem(void)
__reserved_mem_init_node(rmem);
}
 }
+
+static inline struct reserved_mem *__find_rmem(struct device_node *node)
+{
+   unsigned int i;
+
+   if (!node-phandle)
+   return NULL;
+
+   for (i = 0; i  reserved_mem_count; i++)
+   if (reserved_mem[i].phandle == node-phandle)
+   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 reserved_mem *rmem;
+   struct device_node *np;
+
+   np = of_parse_phandle(dev-of_node, memory-region, 0);
+   if (!np)
+   return;
+
+   rmem = __find_rmem(np);
+   of_node_put(np);
+
+   if (!rmem || !rmem-ops || !rmem-ops-device_init)
+   return;
+
+   rmem-ops-device_init(rmem, dev);
+   dev_info(dev, assigned reserved memory node %s\n, rmem-name);
+}
+
+/**
+ * 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 reserved_mem *rmem;
+   struct device_node *np;
+
+   np = of_parse_phandle(dev-of_node, memory-region, 0);
+   if (!np)
+   return;
+
+   rmem = __find_rmem(np);
+   of_node_put(np);
+
+   if (!rmem || !rmem-ops || !rmem-ops-device_release)
+   return;
+
+   rmem-ops-device_release(rmem, dev);
+}
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index 4669ddfdd5af..5b5efae09135 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -8,6 +8,7 @@ struct reserved_mem_ops;
 struct reserved_mem {
const char  *name;
unsigned long   fdt_node;
+   unsigned long   phandle;
const struct reserved_mem_ops   *ops;
phys_addr_t base;
phys_addr_t size;
@@ -27,10 +28,16 @@ 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);
+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 void of_reserved_mem_device_release(struct device *pdev) { }
+
 static inline void fdt_init_reserved_mem(void) { }
 static inline void fdt_reserved_mem_save_node(unsigned long node,
const char *uname, phys_addr_t base, phys_addr_t size) { }
-- 
1.9.2

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


[PATCH v2 RESEND 0/4] CMA device tree, once again

2014-07-14 Thread Marek Szyprowski
Hello,

(please ignore previous patchset, I've attached wrong version of patches)

This is one more respin of the patches which add support for creating
reserved memory regions defined in device tree. The last attempt
(http://lists.linaro.org/pipermail/linaro-mm-sig/2014-February/003738.html)
ended in merging only half of the code, so right now we have complete
documentation merged and only basic code, which implements a half of it
is written in the documentation. Although the merged patches allow to
reserve memory, there is no way of using it for devices and drivers.

This situation makes CMA rather useless, as the main architecture (ARM),
which used it, has been converted from board-file based system
initialization to device tree. Thus there is no place to use direct
calls to dma_declare_contiguous() and some new solution, which bases on
device tree, is urgently needed.

This patch series fixes this issue. It provides two, already widely
discussed and already present in the kernel, drivers for reserved
memory: first based on DMA-coherent allocator, second using Contiguous
Memory Allocator. The first one nicely implements typical 'carved out'
reserved memory way of allocating contiguous buffers in a kernel-style
way. The memory is used exclusively by devices assigned to the given
memory region. The second one allows to reuse reserved memory for
movable kernel pages (like disk buffers, anonymous memory) and migrates
it out when device to allocates contiguous memory buffer. Both driver
provides memory buffers via standard dma-mapping API.

The patches have been rebased on top of latest CMA and mm changes merged
to akmp kernel tree.

To define a 64MiB CMA region following node is needed:

multimedia_reserved: multimedia_mem_region {
compatible = shared-dma-pool;
reusable;
size = 0x400;
alignment = 0x40;
};

Similarly, one can define 64MiB region with DMA coherent memory:

multimedia_reserved: multimedia_mem_region {
compatible = shared-dma-pool;
no-map;
size = 0x400;
alignment = 0x40;
};

Then the defined region can be assigned to devices:

scaler: scaler@1250 {
memory-region = multimedia_reserved;
/* ... */
};
codec: codec@1260 {
memory-region = multimedia_reserved;
/* ... */
};

Best regards
Marek Szyprowski
Samsung RD Institute Poland

Changes since v1:
(http://www.spinics.net/lists/arm-kernel/msg343702.html)
- fixed possible memory leak in case of reserved memory allocation failure
  (thanks to Joonsoo Kim)

Changes since the version posted in '[PATCH v6 00/11] reserved-memory 
regions/CMA in devicetree, again' thread 
http://lists.linaro.org/pipermail/linaro-mm-sig/2014-February/003738.html:
- rebased on top of '[PATCH v3 -next 0/9] CMA: generalize CMA reserved
area management code' patch series on v3.16-rc3
- improved dma-coherent driver, now it correctly handles assigning more
than one device to the given memory region


Patch summary:

Marek Szyprowski (4):
  drivers: of: add automated assignment of reserved regions to client
devices
  drivers: of: initialize and assign reserved memory to newly created
devices
  drivers: dma-coherent: add initialization from device tree
  drivers: dma-contiguous: add initialization from device tree

 drivers/base/dma-coherent.c | 137 ++--
 drivers/base/dma-contiguous.c   |  67 
 drivers/of/of_reserved_mem.c|  70 
 drivers/of/platform.c   |   7 ++
 include/linux/cma.h |   3 +
 include/linux/of_reserved_mem.h |   7 ++
 mm/cma.c|  62 ++
 7 files changed, 323 insertions(+), 30 deletions(-)

-- 
1.9.2

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


[PATCH v2 RESEND 1/4] drivers: of: add automated assignment of reserved regions to client devices

2014-07-14 Thread Marek Szyprowski
This patch adds code for automated assignment of reserved memory regions
to struct device. reserved_mem-ops-device_init()/device_cleanup()
callbacks are called to perform reserved memory driver specific
initialization and cleanup

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/of/of_reserved_mem.c| 70 +
 include/linux/of_reserved_mem.h |  7 +
 2 files changed, 77 insertions(+)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 632aae861375..59fb12e84e6b 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -206,8 +206,16 @@ void __init fdt_init_reserved_mem(void)
for (i = 0; i  reserved_mem_count; i++) {
struct reserved_mem *rmem = reserved_mem[i];
unsigned long node = rmem-fdt_node;
+   int len;
+   const __be32 *prop;
int err = 0;
 
+   prop = of_get_flat_dt_prop(node, phandle, len);
+   if (!prop)
+   prop = of_get_flat_dt_prop(node, linux,phandle, len);
+   if (prop)
+   rmem-phandle = of_read_number(prop, len/4);
+
if (rmem-size == 0)
err = __reserved_mem_alloc_size(node, rmem-name,
 rmem-base, rmem-size);
@@ -215,3 +223,65 @@ void __init fdt_init_reserved_mem(void)
__reserved_mem_init_node(rmem);
}
 }
+
+static inline struct reserved_mem *__find_rmem(struct device_node *node)
+{
+   unsigned int i;
+
+   if (!node-phandle)
+   return NULL;
+
+   for (i = 0; i  reserved_mem_count; i++)
+   if (reserved_mem[i].phandle == node-phandle)
+   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 reserved_mem *rmem;
+   struct device_node *np;
+
+   np = of_parse_phandle(dev-of_node, memory-region, 0);
+   if (!np)
+   return;
+
+   rmem = __find_rmem(np);
+   of_node_put(np);
+
+   if (!rmem || !rmem-ops || !rmem-ops-device_init)
+   return;
+
+   rmem-ops-device_init(rmem, dev);
+   dev_info(dev, assigned reserved memory node %s\n, rmem-name);
+}
+
+/**
+ * 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 reserved_mem *rmem;
+   struct device_node *np;
+
+   np = of_parse_phandle(dev-of_node, memory-region, 0);
+   if (!np)
+   return;
+
+   rmem = __find_rmem(np);
+   of_node_put(np);
+
+   if (!rmem || !rmem-ops || !rmem-ops-device_release)
+   return;
+
+   rmem-ops-device_release(rmem, dev);
+}
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index 4669ddfdd5af..5b5efae09135 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -8,6 +8,7 @@ struct reserved_mem_ops;
 struct reserved_mem {
const char  *name;
unsigned long   fdt_node;
+   unsigned long   phandle;
const struct reserved_mem_ops   *ops;
phys_addr_t base;
phys_addr_t size;
@@ -27,10 +28,16 @@ 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);
+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 void of_reserved_mem_device_release(struct device *pdev) { }
+
 static inline void fdt_init_reserved_mem(void) { }
 static inline void fdt_reserved_mem_save_node(unsigned long node,
const char *uname, phys_addr_t base, phys_addr_t size) { }
-- 
1.9.2

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


[PATCH v2 RESEND 4/4] drivers: dma-contiguous: add initialization from device tree

2014-07-14 Thread Marek Szyprowski
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 jo...@codeaurora.org

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

diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 6606abdf880c..b77ea8bac176 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -211,3 +211,70 @@ 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 void rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev)
+{
+   struct cma *cma = rmem-priv;
+   dev_set_cma_area(dev, cma);
+}
+
+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 32cab7a425f9..9a18a2b1934c 100644
--- a/include/linux/cma.h
+++ b/include/linux/cma.h
@@ -16,6 +16,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 4b251b037e1b..b3d8b925ad34 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -140,6 +140,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

[PATCH v2 RESEND 2/4] drivers: of: initialize and assign reserved memory to newly created devices

2014-07-14 Thread Marek Szyprowski
Use recently introduced of_reserved_mem_device_init() function to
automatically assign respective reserved memory region to the newly created
platform and amba device.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/of/platform.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 500436f9be7f..a9055d3da5c2 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[] = {
@@ -233,12 +234,15 @@ 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
 */
 
if (of_device_add(dev) != 0) {
+   of_reserved_mem_device_release(dev-dev);
platform_device_put(dev);
goto err_clear_flag;
}
@@ -300,6 +304,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)
@@ -326,6 +332,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);
 err_clear_flag:
of_node_clear_flag(node, OF_POPULATED);
-- 
1.9.2

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


[PATCH v2 RESEND 3/4] drivers: dma-coherent: add initialization from device tree

2014-07-14 Thread Marek Szyprowski
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.szyprow...@samsung.com
---
 drivers/base/dma-coherent.c | 137 ++--
 1 file changed, 118 insertions(+), 19 deletions(-)

diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
index 7d6e84a51424..7185a4f247e1 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

Re: [PATCH 4/4] drivers: dma-contiguous: add initialization from device tree

2014-07-07 Thread Marek Szyprowski

Hello,

On 2014-07-04 07:52, Joonsoo Kim wrote:

-Original Message-
From: Marek Szyprowski [mailto:m.szyprow...@samsung.com]
Sent: Wednesday, July 02, 2014 7:49 PM

Subject: [PATCH 4/4] drivers: dma-contiguous: add initialization from
device tree

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

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
  drivers/base/dma-contiguous.c | 67
+
  include/linux/cma.h   |  3 ++
  mm/cma.c  | 69

---

  3 files changed, 122 insertions(+), 17 deletions(-)



...


+/**
   * 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),
@@ -162,18 +210,12 @@ 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;
-   int ret = 0;
+   int ret;

pr_debug(%s(size %lx, base %08lx, limit %08lx alignment %08lx)\n,
__func__, (unsigned long)size, (unsigned long)base,
(unsigned long)limit, (unsigned long)alignment);

-   if (cma_area_count == ARRAY_SIZE(cma_areas)) {
-   pr_err(Not enough slots for CMA reserved regions!\n);
-   return -ENOSPC;
-   }
-

Hello, Marek.

After this change, if we have not enough cma_areas, memory will leak.
I think that we need separate function to check constraint and this
function should be called before reserving memory in
cma_declare_contiguous().


Well, I will leave this check to avoid memory leak then.


BTW, this mail doesn't appear in LKML. What happens? :)


I have no idea, I will send second version then.

Best regards
--
Marek Szyprowski, PhD
Samsung RD Institute Poland

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


Re: [PATCH V2 0/2] Sound support for Exynos4412 Odroid X2, U3 board

2014-06-24 Thread Marek Szyprowski

Hello,

On 2014-06-24 10:35, Daniel Drake wrote:

On Mon, Jun 23, 2014 at 5:32 PM, Sylwester Nawrocki
s.nawro...@samsung.com wrote:

I could reproduce such behaviour on the U3 board, but only with u-boot
which sets the MPLL clock frequency (fout_mpll) to 880 MHz, rather
than 800 MHz, which was the case in my original environment.
All fout_mpll child clocks have then different frequency values
in both cases.
It's a bit strange though, because frequencies of all the audio
subsystem clocks seem to be same anyway:

I'm using the standard uboot from hardkernel.


# cat /sys/kernel/debug/clk/clk_summary

This command makes the kernel totally hang, weird.


This is known issue with clocks vs. ISP power domain. We should really 
fix this in exynos4 clock driver.



# speaker-test -c 2 -t wav -l 2 -p 1024

This plays back fine.

Could it be a problem with the samsung-i2s driver, not correctly
flushing at the right times?
Or do you think the problem is more likely to be clock-related?


Hard to say right now, but at least we need to test a bit more our 
solutions with different initial clocks configuration.


Best regards
--
Marek Szyprowski, PhD
Samsung RD Institute Poland

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


Re: [PATCH 1/6] of: align RESERVEDMEM_OF_DECLARE function callbacks to other callbacks

2014-05-09 Thread Marek Szyprowski

Hello,

On 2014-05-09 00:23, Rob Herring wrote:

From: Rob Herring r...@kernel.org

All the parameters for RESERVEDMEM_OF_DECLARE function callbacks are
members of struct reserved_mem, so just pass the struct ptr to callback
functions so the function callback is more in line with other OF match
table callbacks.

Cc: Marek Szyprowski m.szyprow...@samsung.com
Cc: Grant Likely grant.lik...@linaro.org
Signed-off-by: Rob Herring r...@kernel.org


Acked-by: Marek Szyprowski m.szyprow...@samsung.com


---
  drivers/of/of_reserved_mem.c| 2 +-
  include/linux/of_reserved_mem.h | 4 ++--
  2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index e420eb5..632aae8 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -188,7 +188,7 @@ static int __init __reserved_mem_init_node(struct 
reserved_mem *rmem)
if (!of_flat_dt_is_compatible(rmem-fdt_node, compat))
continue;
  
-		if (initfn(rmem, rmem-fdt_node, rmem-name) == 0) {

+   if (initfn(rmem) == 0) {
pr_info(Reserved memory: initialized node %s, compatible id 
%s\n,
rmem-name, compat);
return 0;
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index 9b1fbb7..4c81b84 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -21,8 +21,8 @@ struct reserved_mem_ops {
  struct device *dev);
  };
  
-typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem,

- unsigned long node, const char *uname);
+typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem);
+
  
  #ifdef CONFIG_OF_RESERVED_MEM

  void fdt_init_reserved_mem(void);


Best regards
--
Marek Szyprowski, PhD
Samsung RD Institute Poland

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


Re: [PATCH v5 01/11] of: document bindings for reserved-memory nodes

2014-02-28 Thread Marek Szyprowski

Hello,

On 2014-02-26 12:51, Grant Likely wrote:

On Fri, 21 Feb 2014 13:25:17 +0100, Marek Szyprowski m.szyprow...@samsung.com 
wrote:
 From: Grant Likely grant.lik...@linaro.org

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

 Signed-off-by: Grant Likely grant.lik...@linaro.org
 [joshc: Based on binding document proposed (in non-patch form) here:
  http://lkml.kernel.org/g/20131030134702.19b57c40...@trevor.secretlab.ca
  adapted to support #memory-region-cells]
 Signed-off-by: Josh Cartwright jo...@codeaurora.org
 Signed-off-by: Marek Szyprowski m.szyprow...@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 ..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 still don't like this portion of the binding. I'm not convinced that
it is necessary in the majority of cases and it is going to be very
driver specific. I would rather drop it entirely from the common
binding. If a specific driver needs to do something like the above then
it can have a driver specific binding. Otherwise I think the default
should be a simple phandle with no arguments to a single reserved memory
node.

Ben, can you weigh in on the current state of this document. I'm mostly
happy with it aside from my comment above. Do you think this is ready to
be merged?

 +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

Add Use vendor strings to identify regions dedicates for a specific
vendor device. For example: 'acme,framebuffer'. Platform code can use vendor
strings to identify device specific regions


So do you want to completely drop phandle based links between device 
nodes and

memory regions?


 +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

[PATCH v6 00/11] reserved-memory regions/CMA in devicetree, again

2014-02-28 Thread Marek Szyprowski
Hello again!

Here is another update of the support for reserved memory regions in
device tree. I've fixes a few more minor issues pointed by Grant. See
changelog for more details.

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 and links below.

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

Changelog:

v6:
- removed the need for #memory-region-cells property
- fixed compilation issues on some systems
- some other minor code cleanups

v5: https://lkml.org/lkml/2014/2/21/147
- sliced main patch into several smaller patches on Grant's request
- fixed coding style issues pointed by Grant
- use node-phandle value directly instead of parsing properties manually

v4: https://lkml.org/lkml/2014/2/20/150
- dynamic allocations are processed after all static reservations has been
  done
- moved code for handling static reservations to drivers/of/fdt.c
- removed node matching by string comparison, now phandle values are used
  directly
- moved code for DMA and CMA handling directly to
  drivers/base/dma-{coherent,contiguous}.c
- added checks for proper #size-cells, #address-cells, ranges properties
  in /reserved-memory node
- even more code cleanup
- added init code for ARM64 and PowerPC

v3: http://article.gmane.org/gmane.linux.documentation/20169/
- refactored memory reservation code, created common code to parse reg, size,
  align, alloc-ranges properties
- added support for multiple tuples in 'reg' property
- memory is reserved regardless of presence of the driver for its compatible
- prepared arch specific hooks for memory reservation (defaults use memblock
  calls)
- removed node matching by string during device initialization
- CMA init code: added checks for required region alignment
- more code cleanup here and there

v2: http://thread.gmane.org/gmane.linux.documentation/19870/
- 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

Marek Szyprowski (10):
  drivers: of: add initialization code for static reserved memory
  drivers: of: add initialization code for dynamic reserved memory
  drivers: of: add support for custom reserved memory drivers
  drivers: of: add automated assignment of reserved regions to client
devices
  drivers: of: initialize and assign reserved memory to newly created
devices
  drivers: dma-coherent: add initialization from device tree
  drivers: dma-contiguous: add initialization from device tree
  arm: add support for reserved memory defined by device tree
  arm64: add support for reserved memory defined by device tree
  powerpc: add support for reserved memory defined by device tree

 .../bindings/reserved-memory/reserved-memory.txt   |  136 ++
 arch/arm/Kconfig   |1 +
 arch/arm/mm/init.c |2 +
 arch/arm64/Kconfig |1 +
 arch/arm64/mm/init.c   |1 +
 arch/powerpc/Kconfig   |1 +
 arch/powerpc/kernel/prom.c |3 +
 drivers/base/dma-coherent.c|   40 +++
 drivers/base/dma-contiguous.c  |  129 +++--
 drivers/of/Kconfig |6 +
 drivers/of/Makefile|1 +
 drivers

[PATCH v6 01/11] of: document bindings for reserved-memory nodes

2014-02-28 Thread Marek Szyprowski
From: Grant Likely grant.lik...@linaro.org

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

Signed-off-by: Grant Likely grant.lik...@linaro.org
[joshc: Based on binding document proposed (in non-patch form) here:
 http://lkml.kernel.org/g/20131030134702.19b57c40...@trevor.secretlab.ca
 adapted to support #memory-region-cells]
Signed-off-by: Josh Cartwright jo...@codeaurora.org
[mszyprow: removed #memory-region-cells property]
Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 .../bindings/reserved-memory/reserved-memory.txt   |  136 
 1 file changed, 136 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 ..8b0d747a38e7
--- /dev/null
+++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
@@ -0,0 +1,136 @@
+*** 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
+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@7200 and 64MiB in size),
+one dedicated to the framebuffer device (named framebuffer@7800, 8MiB), and
+one for multimedia processing

[PATCH v6 05/11] drivers: of: add automated assignment of reserved regions to client devices

2014-02-28 Thread Marek Szyprowski
This patch adds code for automated assignment of reserved memory regions
to struct device. reserved_mem-ops-device_init()/device_cleanup()
callbacks are called to perform reserved memory driver specific
initialization and cleanup

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/of/of_reserved_mem.c|   70 +++
 include/linux/of_reserved_mem.h |7 
 2 files changed, 77 insertions(+)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index daaaf935911d..5c45016efd31 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -206,8 +206,16 @@ void __init fdt_init_reserved_mem(void)
for (i = 0; i  reserved_mem_count; i++) {
struct reserved_mem *rmem = reserved_mem[i];
unsigned long node = rmem-fdt_node;
+   unsigned long len;
+   __be32 *prop;
int err = 0;
 
+   prop = of_get_flat_dt_prop(node, phandle, len);
+   if (!prop)
+   prop = of_get_flat_dt_prop(node, linux,phandle, len);
+   if (prop)
+   rmem-phandle = of_read_number(prop, len/4);
+
if (rmem-size == 0)
err = __reserved_mem_alloc_size(node, rmem-name,
 rmem-base, rmem-size);
@@ -215,3 +223,65 @@ void __init fdt_init_reserved_mem(void)
__reserved_mem_init_node(rmem);
}
 }
+
+static inline struct reserved_mem *__find_rmem(struct device_node *node)
+{
+   unsigned int i;
+
+   if (!node-phandle)
+   return NULL;
+
+   for (i = 0; i  reserved_mem_count; i++)
+   if (reserved_mem[i].phandle == node-phandle)
+   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 reserved_mem *rmem;
+   struct device_node *np;
+
+   np = of_parse_phandle(dev-of_node, memory-region, 0);
+   if (!np)
+   return;
+
+   rmem = __find_rmem(np);
+   of_node_put(np);
+
+   if (!rmem || !rmem-ops || !rmem-ops-device_init)
+   return;
+
+   rmem-ops-device_init(rmem, dev);
+   dev_info(dev, assigned reserved memory node %s\n, rmem-name);
+}
+
+/**
+ * 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 reserved_mem *rmem;
+   struct device_node *np;
+
+   np = of_parse_phandle(dev-of_node, memory-region, 0);
+   if (!np)
+   return;
+
+   rmem = __find_rmem(np);
+   of_node_put(np);
+
+   if (!rmem || !rmem-ops || !rmem-ops-device_release)
+   return;
+
+   rmem-ops-device_release(rmem, dev);
+}
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index 9b1fbb7f29fc..6a54e6565b89 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -8,6 +8,7 @@ struct reserved_mem_ops;
 struct reserved_mem {
const char  *name;
unsigned long   fdt_node;
+   unsigned long   phandle;
const struct reserved_mem_ops   *ops;
phys_addr_t base;
phys_addr_t size;
@@ -25,6 +26,9 @@ 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 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);
@@ -37,6 +41,9 @@ void fdt_reserved_mem_save_node(unsigned long node, const 
char *uname,
init : init }
 
 #else
+static inline void of_reserved_mem_device_init(struct device *dev) { }
+static inline void of_reserved_mem_device_release(struct device *pdev) { }
+
 static inline void fdt_init_reserved_mem(void) { }
 static inline void fdt_reserved_mem_save_node(unsigned long node,
const char *uname, phys_addr_t base, phys_addr_t size) { }
-- 
1.7.9.5

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


[PATCH v6 10/11] arm64: add support for reserved memory defined by device tree

2014-02-28 Thread Marek Szyprowski
Enable reserved memory initialization from device tree.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 arch/arm64/Kconfig   |1 +
 arch/arm64/mm/init.c |1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 27bbcfc7202a..6abf15407dca 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -43,6 +43,7 @@ config ARM64
select NO_BOOTMEM
select OF
select OF_EARLY_FLATTREE
+   select OF_RESERVED_MEM
select PERF_USE_VMALLOC
select POWER_RESET
select POWER_SUPPLY
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index d0b4c2efda90..3fb8d50dfdaa 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -160,6 +160,7 @@ void __init arm64_memblock_init(void)
memblock_reserve(base, size);
}
 
+   early_init_fdt_scan_reserved_mem();
dma_contiguous_reserve(0);
 
memblock_allow_resize();
-- 
1.7.9.5

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


[PATCH v6 04/11] drivers: of: add support for custom reserved memory drivers

2014-02-28 Thread Marek Szyprowski
Add support for custom reserved memory drivers. Call their init() function
for each reserved region and prepare for using operations provided by them
with by the reserved_mem-ops array.

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/of/of_reserved_mem.c  |   29 +
 include/asm-generic/vmlinux.lds.h |   11 +++
 include/linux/of_reserved_mem.h   |   32 
 3 files changed, 72 insertions(+)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 69b811779585..daaaf935911d 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -170,6 +170,33 @@ static int __init __reserved_mem_alloc_size(unsigned long 
node,
return 0;
 }
 
+static const struct of_device_id __rmem_of_table_sentinel
+   __used __section(__reservedmem_of_table_end);
+
+/**
+ * res_mem_init_node() - call region specific reserved memory init code
+ */
+static int __init __reserved_mem_init_node(struct reserved_mem *rmem)
+{
+   extern const struct of_device_id __reservedmem_of_table[];
+   const struct of_device_id *i;
+
+   for (i = __reservedmem_of_table; i  __rmem_of_table_sentinel; i++) {
+   reservedmem_of_init_fn initfn = i-data;
+   const char *compat = i-compatible;
+
+   if (!of_flat_dt_is_compatible(rmem-fdt_node, compat))
+   continue;
+
+   if (initfn(rmem, rmem-fdt_node, rmem-name) == 0) {
+   pr_info(Reserved memory: initialized node %s, 
compatible id %s\n,
+   rmem-name, compat);
+   return 0;
+   }
+   }
+   return -ENOENT;
+}
+
 /**
  * fdt_init_reserved_mem - allocate and init all saved reserved memory regions
  */
@@ -184,5 +211,7 @@ void __init fdt_init_reserved_mem(void)
if (rmem-size == 0)
err = __reserved_mem_alloc_size(node, rmem-name,
 rmem-base, rmem-size);
+   if (err == 0)
+   __reserved_mem_init_node(rmem);
}
 }
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
index 89226ed7d954..9b1fbb7f29fc 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -1,21 +1,53 @@
 #ifndef __OF_RESERVED_MEM_H
 #define __OF_RESERVED_MEM_H
 
+struct device;
+struct of_phandle_args;
+struct reserved_mem_ops;
+
 struct reserved_mem {
const char  *name;
unsigned long   fdt_node;
+   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);
+   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 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);
+
+#define RESERVEDMEM_OF_DECLARE(name, compat, init) \
+   static const struct of_device_id __reservedmem_of_table_

[PATCH v6 11/11] powerpc: add support for reserved memory defined by device tree

2014-02-28 Thread Marek Szyprowski
Enable reserved memory initialization from device tree.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 arch/powerpc/Kconfig   |1 +
 arch/powerpc/kernel/prom.c |3 +++
 2 files changed, 4 insertions(+)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 957bf344c0f5..3b6617fed8fc 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -90,6 +90,7 @@ config PPC
select BINFMT_ELF
select OF
select OF_EARLY_FLATTREE
+   select OF_RESERVED_MEM
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_TRACER
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index f58c0d3aaeb4..591986215801 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -33,6 +33,7 @@
 #include linux/irq.h
 #include linux/memblock.h
 #include linux/of.h
+#include linux/of_fdt.h
 
 #include asm/prom.h
 #include asm/rtas.h
@@ -588,6 +589,8 @@ static void __init early_reserve_mem_dt(void)
memblock_reserve(base, size);
}
}
+
+   early_init_fdt_scan_reserved_mem();
 }
 
 static void __init early_reserve_mem(void)
-- 
1.7.9.5

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


[PATCH v6 06/11] drivers: of: initialize and assign reserved memory to newly created devices

2014-02-28 Thread Marek Szyprowski
Use recently introduced of_reserved_mem_device_init() function to
automatically assign respective reserved memory region to the newly created
platform and amba device.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/of/platform.c |7 +++
 1 file changed, 7 insertions(+)

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;
 }
-- 
1.7.9.5

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


[PATCH v6 08/11] drivers: dma-contiguous: add initialization from device tree

2014-02-28 Thread Marek Szyprowski
Refactor internal dma_contiguous_init_reserved_mem() function, which
creates CMA area from previously reserved memory region and add support
for handling 'shared-dma-pool' reserved-memory device tree nodes.

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/base/dma-contiguous.c |  129 ++---
 1 file changed, 107 insertions(+), 22 deletions(-)

diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 165c2c299e57..0efdf1986990 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -182,6 +182,49 @@ static int __init cma_init_reserved_areas(void)
 core_initcall(cma_init_reserved_areas);
 
 /**
+ * dma_contiguous_init_reserved_mem() - reserve custom contiguous area
+ * @size: Size of the reserved area (in bytes),
+ * @base: Base address of the reserved area optional, use 0 for any
+ * @limit: End address of the reserved memory (optional, 0 for any).
+ * @res_cma: Pointer to store the created cma region.
+ *
+ * This function reserves memory from early allocator. It should be
+ * called by arch specific code once the early allocator (memblock or bootmem)
+ * has been activated and all other subsystems have already allocated/reserved
+ * memory. This function allows to create custom reserved areas for specific
+ * devices.
+ */
+static int __init dma_contiguous_init_reserved_mem(phys_addr_t size,
+   phys_addr_t base, struct cma **res_cma)
+{
+   struct cma *cma = cma_areas[cma_area_count];
+   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;
+
+   /* Sanitise input arguments */
+   alignment = PAGE_SIZE  max(MAX_ORDER - 1, pageblock_order);
+   if (ALIGN(base, alignment) != base || ALIGN(size, alignment) != size)
+   return -EINVAL;
+
+   cma-base_pfn = PFN_DOWN(base);
+   cma-count = size  PAGE_SHIFT;
+   *res_cma = cma;
+   cma_area_count++;
+
+   /* Architecture specific contiguous memory fixup. */
+   dma_contiguous_early_fixup(base, size);
+   return 0;
+}
+
+/**
  * dma_contiguous_reserve_area() - reserve custom contiguous area
  * @size: Size of the reserved area (in bytes),
  * @base: Base address of the reserved area optional, use 0 for any
@@ -197,7 +240,6 @@ core_initcall(cma_init_reserved_areas);
 int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
   phys_addr_t limit, struct cma **res_cma)
 {
-   struct cma *cma = cma_areas[cma_area_count];
phys_addr_t alignment;
int ret = 0;
 
@@ -205,12 +247,6 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, 
phys_addr_t base,
 (unsigned long)size, (unsigned long)base,
 (unsigned long)limit);
 
-   /* Sanity checks */
-   if (cma_area_count == ARRAY_SIZE(cma_areas)) {
-   pr_err(Not enough slots for CMA reserved regions!\n);
-   return -ENOSPC;
-   }
-
if (!size)
return -EINVAL;
 
@@ -241,21 +277,12 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, 
phys_addr_t base,
}
}
 
-   /*
-* Each reserved area must be initialised later, when more kernel
-* subsystems (like slab allocator) are available.
-*/
-   cma-base_pfn = PFN_DOWN(base);
-   cma-count = size  PAGE_SHIFT;
-   *res_cma = cma;
-   cma_area_count++;
-
-   pr_info(CMA: reserved %ld MiB at %08lx\n, (unsigned long)size / SZ_1M,
-   (unsigned long)base);
-
-   /* Architecture specific contiguous memory fixup. */
-   dma_contiguous_early_fixup(base, size);
-   return 0;
+   ret = dma_contiguous_init_reserved_mem(size, base, res_cma);
+   if (ret == 0) {
+   pr_info(CMA: reserved %ld MiB at %08lx\n,
+   (unsigned long)size / SZ_1M, (unsigned long)base);
+   return 0;
+   }
 err:
pr_err(CMA: failed to reserve %ld MiB\n, (unsigned long)size / SZ_1M);
return ret;
@@ -357,3 +384,61 @@ bool dma_release_from_contiguous(struct device *dev, 
struct page *pages,
 
return true;
 }
+
+/*
+ * 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 void rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev)
+{
+   struct cma *cma = rmem-priv;
+   dev_set_cma_area(dev, cma);
+}
+
+static const struct reserved_mem_ops rmem_cma_ops

[PATCH v6 03/11] drivers: of: add initialization code for dynamic reserved memory

2014-02-28 Thread Marek Szyprowski
This patch adds support for dynamically allocated reserved memory regions
declared in device tree. Such regions are defined by 'size', 'alignment'
and 'alloc-ranges' properties.

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
Acked-by: Grant Likely grant.lik...@linaro.org
---
 drivers/of/Kconfig  |6 ++
 drivers/of/Makefile |1 +
 drivers/of/fdt.c|   13 ++-
 drivers/of/of_reserved_mem.c|  188 +++
 include/linux/of_reserved_mem.h |   21 +
 5 files changed, 227 insertions(+), 2 deletions(-)
 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..30a7d87a8077 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 OF_EARLY_FLATTREE
+   bool
+   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/fdt.c b/drivers/of/fdt.c
index 819e11209718..510c0d8de8a0 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -15,6 +15,7 @@
 #include linux/module.h
 #include linux/of.h
 #include linux/of_fdt.h
+#include linux/of_reserved_mem.h
 #include linux/sizes.h
 #include linux/string.h
 #include linux/errno.h
@@ -450,7 +451,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long 
node,
phys_addr_t base, size;
unsigned long len;
__be32 *prop;
-   int nomap;
+   int nomap, first = 1;
 
prop = of_get_flat_dt_prop(node, reg, len);
if (!prop)
@@ -477,6 +478,10 @@ static int __init __reserved_mem_reserve_reg(unsigned long 
node,
uname, base, (unsigned long)size / SZ_1M);
 
len -= t_len;
+   if (first) {
+   fdt_reserved_mem_save_node(node, uname, base, size);
+   first = 0;
+   }
}
return 0;
 }
@@ -512,6 +517,7 @@ static int __init __fdt_scan_reserved_mem(unsigned long 
node, const char *uname,
 {
static int found;
const char *status;
+   int err;
 
if (!found  depth == 1  strcmp(uname, reserved-memory) == 0) {
if (__reserved_mem_check_root(node) != 0) {
@@ -534,7 +540,9 @@ static int __init __fdt_scan_reserved_mem(unsigned long 
node, const char *uname,
if (status  strcmp(status, okay) != 0  strcmp(status, ok) != 0)
return 0;
 
-   __reserved_mem_reserve_reg(node, uname);
+   err = __reserved_mem_reserve_reg(node, uname);
+   if (err == -ENOENT  of_get_flat_dt_prop(node, size, NULL))
+   fdt_reserved_mem_save_node(node, uname, 0, 0);
 
/* scan next node */
return 0;
@@ -550,6 +558,7 @@ static int __init __fdt_scan_reserved_mem(unsigned long 
node, const char *uname,
 void __init early_init_fdt_scan_reserved_mem(void)
 {
of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);
+   fdt_init_reserved_mem();
 }
 
 /**
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
new file mode 100644
index ..69b811779585
--- /dev/null
+++ b/drivers/of/of_reserved_mem.c
@@ -0,0 +1,188 @@
+/*
+ * Device tree based initialization code for reserved memory.
+ *
+ * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
+ * Copyright (c) 2013,2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Author: Marek Szyprowski m.szyprow...@samsung.com
+ * Author: Josh Cartwright jo...@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/of_reserved_mem.h
+
+#define MAX_RESERVED_REGIONS   16
+static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
+static int reserved_mem_count;
+
+#if defined(CONFIG_HAVE_MEMBLOCK)
+#include linux/memblock.h
+int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
+   phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
+   phys_addr_t *res_base)
+{
+   /*
+* We use

[PATCH v6 02/11] drivers: of: add initialization code for static reserved memory

2014-02-28 Thread Marek Szyprowski
This patch adds support for static (defined by 'reg' property) reserved
memory regions declared in device tree.

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). Typically, all this happens before device tree
structures are unflattened, so we need to get reserved memory layout
directly from fdt.

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
Acked-by: Grant Likely grant.lik...@linaro.org
---
 drivers/of/fdt.c   |  131 
 include/linux/of_fdt.h |3 ++
 2 files changed, 134 insertions(+)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 758b4f8b30b7..819e11209718 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -15,6 +15,7 @@
 #include linux/module.h
 #include linux/of.h
 #include linux/of_fdt.h
+#include linux/sizes.h
 #include linux/string.h
 #include linux/errno.h
 #include linux/slab.h
@@ -440,6 +441,118 @@ struct boot_param_header *initial_boot_params;
 #ifdef CONFIG_OF_EARLY_FLATTREE
 
 /**
+ * res_mem_reserve_reg() - reserve all memory described in 'reg' property
+ */
+static int __init __reserved_mem_reserve_reg(unsigned long node,
+const char *uname)
+{
+   int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
+   phys_addr_t base, size;
+   unsigned long len;
+   __be32 *prop;
+   int nomap;
+
+   prop = of_get_flat_dt_prop(node, reg, len);
+   if (!prop)
+   return -ENOENT;
+
+   if (len  len % t_len != 0) {
+   pr_err(Reserved memory: invalid reg property in '%s', skipping 
node.\n,
+  uname);
+   return -EINVAL;
+   }
+
+   nomap = of_get_flat_dt_prop(node, no-map, NULL) != NULL;
+
+   while (len = t_len) {
+   base = dt_mem_next_cell(dt_root_addr_cells, prop);
+   size = dt_mem_next_cell(dt_root_size_cells, prop);
+
+   if (base  size 
+   early_init_dt_reserve_memory_arch(base, size, nomap) == 0)
+   pr_debug(Reserved memory: reserved region for node 
'%s': base %pa, size %ld MiB\n,
+   uname, base, (unsigned long)size / SZ_1M);
+   else
+   pr_info(Reserved memory: failed to reserve memory for 
node '%s': base %pa, size %ld MiB\n,
+   uname, base, (unsigned long)size / SZ_1M);
+
+   len -= t_len;
+   }
+   return 0;
+}
+
+/**
+ * __reserved_mem_check_root() - check if #size-cells, #address-cells provided
+ * in /reserved-memory matches the values supported by the current 
implementation,
+ * also check if ranges property has been provided
+ */
+static int __reserved_mem_check_root(unsigned long node)
+{
+   __be32 *prop;
+
+   prop = of_get_flat_dt_prop(node, #size-cells, NULL);
+   if (!prop || be32_to_cpup(prop) != dt_root_size_cells)
+   return -EINVAL;
+
+   prop = of_get_flat_dt_prop(node, #address-cells, NULL);
+   if (!prop || be32_to_cpup(prop) != dt_root_addr_cells)
+   return -EINVAL;
+
+   prop = of_get_flat_dt_prop(node, ranges, NULL);
+   if (!prop)
+   return -EINVAL;
+   return 0;
+}
+
+/**
+ * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory
+ */
+static int __init __fdt_scan_reserved_mem(unsigned long node, const char 
*uname,
+ int depth, void *data)
+{
+   static int found;
+   const char *status;
+
+   if (!found  depth == 1  strcmp(uname, reserved-memory) == 0) {
+   if (__reserved_mem_check_root(node) != 0) {
+   pr_err(Reserved memory: unsupported node format, 
ignoring\n);
+   /* break scan */
+   return 1;
+   }
+   found = 1;
+   /* scan next node */
+   return 0;
+   } else if (!found) {
+   /* scan next node */
+   return 0;
+   } else if (found  depth  2) {
+   /* scanning of /reserved-memory has been finished */
+   return 1;
+   }
+
+   status = of_get_flat_dt_prop(node, status, NULL);
+   if (status  strcmp(status, okay) != 0  strcmp(status, ok) != 0)
+   return 0;
+
+   __reserved_mem_reserve_reg(node, uname);
+
+   /* scan next node */
+   return 0;
+}
+
+/**
+ * early_init_fdt_scan_reserved_mem() - create reserved memory regions
+ *
+ * This function grabs memory from early allocator for device exclusive

[PATCH v6 07/11] drivers: dma-coherent: add initialization from device tree

2014-02-28 Thread Marek Szyprowski
Add support for handling 'shared-dma-pool' reserved-memory device tree
nodes.

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/base/dma-coherent.c |   40 
 1 file changed, 40 insertions(+)

diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
index bc256b641027..0a5fc7f3d03e 100644
--- a/drivers/base/dma-coherent.c
+++ b/drivers/base/dma-coherent.c
@@ -218,3 +218,43 @@ 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 void rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
+{
+   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)
+{
+   if (of_get_flat_dt_prop(node, reusable, NULL))
+   return -EINVAL;
+
+   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.7.9.5

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


Re: [PATCH v5 06/11] drivers: of: initialize and assign reserved memory to newly created devices

2014-02-27 Thread Marek Szyprowski

Hello,

On 2014-02-26 13:14, Grant Likely wrote:

On Fri, 21 Feb 2014 13:25:22 +0100, Marek Szyprowski m.szyprow...@samsung.com 
wrote:
 Use recently introduced of_reserved_mem_device_init() function to
 automatically assign respective reserved memory region to the newly created
 platform and amba device.

 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com

I'm wary on this patch. It hides the assignment of regions into the core
code and I worry that it is the wrong level of abstraction. I would
think that drivers should know that they need a reserved memory region
and should be calling the API to obtain the region directly rather than
doing it for them. The reason being is that there may be some situations
where the common code isn't quite right and the driver needs to override
the behaviour. If it is called automatically then the driver cannot do
that.

Is it really a big burden to have the driver call the reserved memory
init function?


If a device requires very special handling of the reserved memory region,
it may simply provide its own reserved memory region driver which will do
the required early initialization.

If we assume that driver needs to initialize reserved region manually, then
why do we ever bother with adding support for custom reserved memory drivers
and assigning regions to a device node? We can simply stick with just a set
of reserved regions and tell drivers to use them.

In my opinion for most typical use cases a board designer will assign
'dma-shared-pool' driver to the given set of devices, which in turn ensures
that all memory allocations for dma purposes for those device will be
served from that region. It is really not a driver role to initialize it
in such case. Driver should focus on controlling hw operations, regardless
the way the hardware module has been integrated to the system.

I can perfectly imagine a generic driver which operates the same way in any
of the following cases (depends mainly on the hw version): 1) restricted
dma window, 2) iommu for all dma for the given device, 3) fully featured
memory master for dma for the given device (no restrictions), if the
respective kernel subsystems did the correct initialization and provide
their own methods for managing DMA operation. I already have a working
platform glue code for the above cases tested with Samsung multimedia
drivers. No changes to the drivers were required.

Best regards
--
Marek Szyprowski, PhD
Samsung RD Institute Poland

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


Re: [PATCH v4 1/7] drivers: of: add initialization code for reserved memory

2014-02-21 Thread Marek Szyprowski

Hello,

On 2014-02-20 15:01, Grant Likely wrote:

On Thu, 20 Feb 2014 11:52:41 +0100, Marek Szyprowski m.szyprow...@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.

 Signed-off-by: Marek Szyprowski m.szyprow...@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 jo...@codeaurora.org
 [mszyprow: added generic memory reservation code, refactored code to
  put it directly into fdt.c]
 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
 ---
  drivers/of/Kconfig|6 +
  drivers/of/Makefile   |1 +
  drivers/of/fdt.c  |  145 ++
  drivers/of/of_reserved_mem.c  |  296 
+
  drivers/of/platform.c |7 +
  include/asm-generic/vmlinux.lds.h |   11 ++
  include/linux/of_reserved_mem.h   |   65 
  7 files changed, 531 insertions(+)
  create mode 100644 drivers/of/of_reserved_mem.c
  create mode 100644 include/linux/of_reserved_mem.h

Hi Marek,

There's a lot of moving parts in this patch. Can you split the patch up a bit 
please. There are parts that I'm not entierly comfortable with yet and it will 
help reviewing them if they are added separately. For instance, the attaching 
regions to devices is something that I want to have some discussion about, but 
the core reserving static ranges I think is pretty much ready to be merged. I 
can merge the later while still debating the former if they are split.

I would recommend splitting into four:
1) reservation of static regions without the support code for referencing them 
later
2) code to also do dynamic allocations of reserved regions - again without any 
driver references
3) add hooks to reference specific regions.
4) hooks into drivers/of/platform.c for wiring into the driver model.

Can you also make the binding doc the first patch?


Ok, I will slice the patch into 4 pieces.

(snipped)


 +/**
 + * res_mem_alloc_size() - allocate reserved memory described by 'size', 
'align'
 + *  and 'alloc-ranges' properties
 + */
 +static int __init
 +__reserved_mem_alloc_size(unsigned long node, const char *uname,
 +phys_addr_t *res_base, phys_addr_t *res_size)
 +{
 +  int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
 +  phys_addr_t start = 0, end = 0;
 +  phys_addr_t base = 0, align = 0, size;
 +  unsigned long len;
 +  __be32 *prop;
 +  int nomap;
 +  int ret;
 +
 +  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);
 +
 +  nomap = of_get_flat_dt_prop(node, no-map, NULL) != NULL;
 +
 +  prop = of_get_flat_dt_prop(node, align, len);
 +  if (prop) {
 +  if (len != dt_root_addr_cells * sizeof(__be32)) {
 +  pr_err(Reserved memory: invalid align property in '%s' 
node.\n,
 +  uname);
 +  return -EINVAL;
 +  }
 +  align = dt_mem_next_cell(dt_root_addr_cells, prop);
 +  }
 +
 +  prop = of_get_flat_dt_prop(node, alloc-ranges, len);
 +  if (prop) {
 +
 +  if (len % t_len != 0) {
 +  pr_err(Reserved memory: invalid alloc-ranges property in '%s', 
skipping node.\n,
 + uname);
 +  return -EINVAL;
 +  }
 +
 +  base = 0;
 +
 +  while (len  0) {
 +  start = dt_mem_next_cell(dt_root_addr_cells, prop);
 +  end = start + dt_mem_next_cell(dt_root_size_cells,
 + prop);
 +
 +  ret = early_init_dt_alloc_reserved_memory_arch(size,
 +  align, start, end, nomap, base);
 +  if (ret == 0) {
 +  pr_debug(Reserved memory: allocated memory for '%s' 
node: base %pa, size %ld MiB\n

[PATCH v5 08/11] drivers: dma-contiguous: add initialization from device tree

2014-02-21 Thread Marek Szyprowski
Refactor internal dma_contiguous_init_reserved_mem() function, which
creates CMA area from previously reserved memory region and add support
for handling 'shared-dma-pool' reserved-memory device tree nodes.

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/base/dma-contiguous.c |  130 ++---
 1 file changed, 108 insertions(+), 22 deletions(-)

diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 165c2c299e57..5dfcc3743d9b 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -182,6 +182,49 @@ static int __init cma_init_reserved_areas(void)
 core_initcall(cma_init_reserved_areas);
 
 /**
+ * dma_contiguous_init_reserved_mem() - reserve custom contiguous area
+ * @size: Size of the reserved area (in bytes),
+ * @base: Base address of the reserved area optional, use 0 for any
+ * @limit: End address of the reserved memory (optional, 0 for any).
+ * @res_cma: Pointer to store the created cma region.
+ *
+ * This function reserves memory from early allocator. It should be
+ * called by arch specific code once the early allocator (memblock or bootmem)
+ * has been activated and all other subsystems have already allocated/reserved
+ * memory. This function allows to create custom reserved areas for specific
+ * devices.
+ */
+static int __init dma_contiguous_init_reserved_mem(phys_addr_t size,
+   phys_addr_t base, struct cma **res_cma)
+{
+   struct cma *cma = cma_areas[cma_area_count];
+   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;
+
+   /* Sanitise input arguments */
+   alignment = PAGE_SIZE  max(MAX_ORDER - 1, pageblock_order);
+   if (ALIGN(base, alignment) != base || ALIGN(size, alignment) != size)
+   return -EINVAL;
+
+   cma-base_pfn = PFN_DOWN(base);
+   cma-count = size  PAGE_SHIFT;
+   *res_cma = cma;
+   cma_area_count++;
+
+   /* Architecture specific contiguous memory fixup. */
+   dma_contiguous_early_fixup(base, size);
+   return 0;
+}
+
+/**
  * dma_contiguous_reserve_area() - reserve custom contiguous area
  * @size: Size of the reserved area (in bytes),
  * @base: Base address of the reserved area optional, use 0 for any
@@ -197,7 +240,6 @@ core_initcall(cma_init_reserved_areas);
 int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
   phys_addr_t limit, struct cma **res_cma)
 {
-   struct cma *cma = cma_areas[cma_area_count];
phys_addr_t alignment;
int ret = 0;
 
@@ -205,12 +247,6 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, 
phys_addr_t base,
 (unsigned long)size, (unsigned long)base,
 (unsigned long)limit);
 
-   /* Sanity checks */
-   if (cma_area_count == ARRAY_SIZE(cma_areas)) {
-   pr_err(Not enough slots for CMA reserved regions!\n);
-   return -ENOSPC;
-   }
-
if (!size)
return -EINVAL;
 
@@ -241,21 +277,12 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, 
phys_addr_t base,
}
}
 
-   /*
-* Each reserved area must be initialised later, when more kernel
-* subsystems (like slab allocator) are available.
-*/
-   cma-base_pfn = PFN_DOWN(base);
-   cma-count = size  PAGE_SHIFT;
-   *res_cma = cma;
-   cma_area_count++;
-
-   pr_info(CMA: reserved %ld MiB at %08lx\n, (unsigned long)size / SZ_1M,
-   (unsigned long)base);
-
-   /* Architecture specific contiguous memory fixup. */
-   dma_contiguous_early_fixup(base, size);
-   return 0;
+   ret = dma_contiguous_init_reserved_mem(size, base, res_cma);
+   if (ret == 0) {
+   pr_info(CMA: reserved %ld MiB at %08lx\n,
+   (unsigned long)size / SZ_1M, (unsigned long)base);
+   return 0;
+   }
 err:
pr_err(CMA: failed to reserve %ld MiB\n, (unsigned long)size / SZ_1M);
return ret;
@@ -357,3 +384,62 @@ bool dma_release_from_contiguous(struct device *dev, 
struct page *pages,
 
return true;
 }
+
+/*
+ * 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 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

[PATCH v5 11/11] powerpc: add support for reserved memory defined by device tree

2014-02-21 Thread Marek Szyprowski
Enable reserved memory initialization from device tree.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 arch/powerpc/Kconfig   |1 +
 arch/powerpc/kernel/prom.c |3 +++
 2 files changed, 4 insertions(+)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 957bf344c0f5..3b6617fed8fc 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -90,6 +90,7 @@ config PPC
select BINFMT_ELF
select OF
select OF_EARLY_FLATTREE
+   select OF_RESERVED_MEM
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_TRACER
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index f58c0d3aaeb4..591986215801 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -33,6 +33,7 @@
 #include linux/irq.h
 #include linux/memblock.h
 #include linux/of.h
+#include linux/of_fdt.h
 
 #include asm/prom.h
 #include asm/rtas.h
@@ -588,6 +589,8 @@ static void __init early_reserve_mem_dt(void)
memblock_reserve(base, size);
}
}
+
+   early_init_fdt_scan_reserved_mem();
 }
 
 static void __init early_reserve_mem(void)
-- 
1.7.9.5

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


[PATCH v5 09/11] arm: add support for reserved memory defined by device tree

2014-02-21 Thread Marek Szyprowski
Enable reserved memory initialization from device tree.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 arch/arm/Kconfig   |1 +
 arch/arm/mm/init.c |2 ++
 2 files changed, 3 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e25419817791..d0262bea8020 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1918,6 +1918,7 @@ config USE_OF
select IRQ_DOMAIN
select OF
select OF_EARLY_FLATTREE
+   select OF_RESERVED_MEM
help
  Include support for flattened device tree machine descriptions.
 
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 804d61566a53..2a77ba8796ae 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -323,6 +323,8 @@ void __init arm_memblock_init(struct meminfo *mi,
if (mdesc-reserve)
mdesc-reserve();
 
+   early_init_fdt_scan_reserved_mem();
+
/*
 * 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 devicetree in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 10/11] arm64: add support for reserved memory defined by device tree

2014-02-21 Thread Marek Szyprowski
Enable reserved memory initialization from device tree.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 arch/arm64/Kconfig   |1 +
 arch/arm64/mm/init.c |1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 27bbcfc7202a..6abf15407dca 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -43,6 +43,7 @@ config ARM64
select NO_BOOTMEM
select OF
select OF_EARLY_FLATTREE
+   select OF_RESERVED_MEM
select PERF_USE_VMALLOC
select POWER_RESET
select POWER_SUPPLY
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index d0b4c2efda90..3fb8d50dfdaa 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -160,6 +160,7 @@ void __init arm64_memblock_init(void)
memblock_reserve(base, size);
}
 
+   early_init_fdt_scan_reserved_mem();
dma_contiguous_reserve(0);
 
memblock_allow_resize();
-- 
1.7.9.5

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


[PATCH v5 05/11] drivers: of: add automated assignment of reserved regions to client devices

2014-02-21 Thread Marek Szyprowski
This patch adds code for automated assignment of reserved memory regions
to struct device. reserved_mem-ops-device_init()/device_cleanup()
callbacks are called to perform reserved memory driver specific
initialization and cleanup. The code looks for 'memory-region' property
in the client device node and assigns region pointed by the found
phandle.

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/of/of_reserved_mem.c|   74 +++
 include/linux/of_reserved_mem.h |7 
 2 files changed, 81 insertions(+)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 97de6f882f85..b02a7f0a54c8 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -206,8 +206,16 @@ void __init fdt_init_reserved_mem(void)
for (i = 0; i  reserved_mem_count; i++) {
struct reserved_mem *rmem = reserved_mem[i];
unsigned long node = rmem-fdt_node;
+   unsigned long len;
+   __be32 *prop;
int err = 0;
 
+   prop = of_get_flat_dt_prop(node, phandle, len);
+   if (!prop)
+   prop = of_get_flat_dt_prop(node, linux,phandle, len);
+   if (prop)
+   rmem-phandle = of_read_number(prop, len/4);
+
if (rmem-size == 0)
err = __reserved_mem_alloc_size(node, rmem-name,
 rmem-base, rmem-size);
@@ -215,3 +223,69 @@ void __init fdt_init_reserved_mem(void)
__reserved_mem_init_node(rmem);
}
 }
+
+static inline struct reserved_mem *__find_rmem(struct device_node *node)
+{
+   unsigned int i;
+
+   if (!node-phandle)
+   return NULL;
+
+   for (i = 0; i  reserved_mem_count; i++)
+   if (reserved_mem[i].phandle == node-phandle)
+   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);
+   }
+}
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index f707176619a3..a2a25de297de 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -8,6 +8,7 @@ struct reserved_mem_ops;
 struct reserved_mem {
const char  *name;
unsigned long   fdt_node;
+   unsigned long   phandle;
const struct reserved_mem_ops   *ops;
phys_addr_t base;
phys_addr_t size;
@@ -26,6 +27,9 @@ 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 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);
@@ -38,6 +42,9 @@ void fdt_reserved_mem_save_node(unsigned long node, const 
char *uname,
init : init }
 
 #else
+static inline void of_reserved_mem_device_init

[PATCH v5 06/11] drivers: of: initialize and assign reserved memory to newly created devices

2014-02-21 Thread Marek Szyprowski
Use recently introduced of_reserved_mem_device_init() function to
automatically assign respective reserved memory region to the newly created
platform and amba device.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/of/platform.c |7 +++
 1 file changed, 7 insertions(+)

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;
 }
-- 
1.7.9.5

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


[PATCH v5 01/11] of: document bindings for reserved-memory nodes

2014-02-21 Thread Marek Szyprowski
From: Grant Likely grant.lik...@linaro.org

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

Signed-off-by: Grant Likely grant.lik...@linaro.org
[joshc: Based on binding document proposed (in non-patch form) here:
 http://lkml.kernel.org/g/20131030134702.19b57c40...@trevor.secretlab.ca
 adapted to support #memory-region-cells]
Signed-off-by: Josh Cartwright jo...@codeaurora.org
Signed-off-by: Marek Szyprowski m.szyprow...@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 ..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@7200 and 64MiB in size),
+one dedicated

[PATCH v5 07/11] drivers: dma-coherent: add initialization from device tree

2014-02-21 Thread Marek Szyprowski
Add support for handling 'shared-dma-pool' reserved-memory device tree
nodes.

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/base/dma-coherent.c |   41 +
 1 file changed, 41 insertions(+)

diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
index bc256b641027..2343ba5d6d43 100644
--- a/drivers/base/dma-coherent.c
+++ b/drivers/base/dma-coherent.c
@@ -218,3 +218,44 @@ 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 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)
+{
+   if (of_get_flat_dt_prop(node, reusable, NULL))
+   return -EINVAL;
+
+   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.7.9.5

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


[PATCH v5 03/11] drivers: of: add initialization code for dynamic reserved memory

2014-02-21 Thread Marek Szyprowski
This patch adds support for dynamically allocated reserved memory regions
declared in device tree. Such regions are defined by 'size', 'alignment'
and 'alloc-ranges' properties.

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/of/Kconfig  |6 ++
 drivers/of/Makefile |1 +
 drivers/of/fdt.c|   13 ++-
 drivers/of/of_reserved_mem.c|  188 +++
 include/linux/of_reserved_mem.h |   21 +
 5 files changed, 227 insertions(+), 2 deletions(-)
 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..30a7d87a8077 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 OF_EARLY_FLATTREE
+   bool
+   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/fdt.c b/drivers/of/fdt.c
index 12809e20ef71..eafe5805257a 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -15,6 +15,7 @@
 #include linux/module.h
 #include linux/of.h
 #include linux/of_fdt.h
+#include linux/of_reserved_mem.h
 #include linux/string.h
 #include linux/errno.h
 #include linux/slab.h
@@ -449,7 +450,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long 
node,
phys_addr_t base, size;
unsigned long len;
__be32 *prop;
-   int nomap;
+   int nomap, first = 1;
 
prop = of_get_flat_dt_prop(node, reg, len);
if (!prop)
@@ -476,6 +477,10 @@ static int __init __reserved_mem_reserve_reg(unsigned long 
node,
uname, base, (unsigned long)size / SZ_1M);
 
len -= t_len;
+   if (first) {
+   fdt_reserved_mem_save_node(node, uname, base, size);
+   first = 0;
+   }
}
return 0;
 }
@@ -506,6 +511,7 @@ static int __init __fdt_scan_reserved_mem(unsigned long 
node, const char *uname,
 {
static int found;
const char *status;
+   int err;
 
if (!found  depth == 1  strcmp(uname, reserved-memory) == 0) {
if (__reserved_mem_check_root(node) != 0) {
@@ -528,7 +534,9 @@ static int __init __fdt_scan_reserved_mem(unsigned long 
node, const char *uname,
if (status  strcmp(status, okay) != 0  strcmp(status, ok) != 0)
return 0;
 
-   __reserved_mem_reserve_reg(node, uname);
+   err = __reserved_mem_reserve_reg(node, uname);
+   if (err == -ENOENT  of_get_flat_dt_prop(node, size, NULL))
+   fdt_reserved_mem_save_node(node, uname, 0, 0);
 
/* scan next node */
return 0;
@@ -544,6 +552,7 @@ static int __init __fdt_scan_reserved_mem(unsigned long 
node, const char *uname,
 void __init early_init_fdt_scan_reserved_mem(void)
 {
of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);
+   fdt_init_reserved_mem();
 }
 
 /**
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
new file mode 100644
index ..c7ca6a4a42d1
--- /dev/null
+++ b/drivers/of/of_reserved_mem.c
@@ -0,0 +1,188 @@
+/*
+ * Device tree based initialization code for reserved memory.
+ *
+ * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
+ * Copyright (c) 2013,2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Author: Marek Szyprowski m.szyprow...@samsung.com
+ * Author: Josh Cartwright jo...@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/of_reserved_mem.h
+
+#define MAX_RESERVED_REGIONS   16
+static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
+static int reserved_mem_count;
+
+#if defined(CONFIG_HAVE_MEMBLOCK)
+#include linux/memblock.h
+int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
+   phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
+   phys_addr_t *res_base)
+{
+   /*
+* We use __memblock_alloc_base() because memblock_alloc_base

[PATCH v5 04/11] drivers: of: add support for custom reserved memory drivers

2014-02-21 Thread Marek Szyprowski
Add support for custom reserved memory drivers. Call their init() function
for each reserved region and prepare for using operations provided by them
with by the reserved_mem-ops array.

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/of/of_reserved_mem.c  |   29 +
 include/asm-generic/vmlinux.lds.h |   11 +++
 include/linux/of_reserved_mem.h   |   33 +
 3 files changed, 73 insertions(+)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index c7ca6a4a42d1..97de6f882f85 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -170,6 +170,33 @@ static int __init __reserved_mem_alloc_size(unsigned long 
node,
return 0;
 }
 
+static const struct of_device_id __rmem_of_table_sentinel
+   __used __section(__reservedmem_of_table_end);
+
+/**
+ * res_mem_init_node() - call region specific reserved memory init code
+ */
+static int __init __reserved_mem_init_node(struct reserved_mem *rmem)
+{
+   extern const struct of_device_id __reservedmem_of_table[];
+   const struct of_device_id *i;
+
+   for (i = __reservedmem_of_table; i  __rmem_of_table_sentinel; i++) {
+   reservedmem_of_init_fn initfn = i-data;
+   const char *compat = i-compatible;
+
+   if (!of_flat_dt_is_compatible(rmem-fdt_node, compat))
+   continue;
+
+   if (initfn(rmem, rmem-fdt_node, rmem-name) == 0) {
+   pr_info(Reserved memory: initialized node %s, 
compatible id %s\n,
+   rmem-name, compat);
+   return 0;
+   }
+   }
+   return -ENOENT;
+}
+
 /**
  * fdt_init_reserved_mem - allocate and init all saved reserved memory regions
  */
@@ -184,5 +211,7 @@ void __init fdt_init_reserved_mem(void)
if (rmem-size == 0)
err = __reserved_mem_alloc_size(node, rmem-name,
 rmem-base, rmem-size);
+   if (err == 0)
+   __reserved_mem_init_node(rmem);
}
 }
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
index 89226ed7d954..f707176619a3 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -1,21 +1,54 @@
 #ifndef __OF_RESERVED_MEM_H
 #define __OF_RESERVED_MEM_H
 
+struct device;
+struct of_phandle_args;
+struct reserved_mem_ops;
+
 struct reserved_mem {
const char  *name;
unsigned long   fdt_node;
+   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 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);
+
+#define RESERVEDMEM_OF_DECLARE(name, compat, init

[PATCH v5 02/11] drivers: of: add initialization code for static reserved memory

2014-02-21 Thread Marek Szyprowski
This patch adds support for static (defined by 'reg' property) reserved
memory regions declared in device tree.

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). Typically, all this happens before device tree
structures are unflattened, so we need to get reserved memory layout
directly from fdt.

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/of/fdt.c   |  125 
 include/linux/of_fdt.h |3 ++
 2 files changed, 128 insertions(+)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 758b4f8b30b7..12809e20ef71 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -440,6 +440,113 @@ struct boot_param_header *initial_boot_params;
 #ifdef CONFIG_OF_EARLY_FLATTREE
 
 /**
+ * res_mem_reserve_reg() - reserve all memory described in 'reg' property
+ */
+static int __init __reserved_mem_reserve_reg(unsigned long node,
+const char *uname)
+{
+   int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
+   phys_addr_t base, size;
+   unsigned long len;
+   __be32 *prop;
+   int nomap;
+
+   prop = of_get_flat_dt_prop(node, reg, len);
+   if (!prop)
+   return -ENOENT;
+
+   if (len  len % t_len != 0) {
+   pr_err(Reserved memory: invalid reg property in '%s', skipping 
node.\n,
+  uname);
+   return -EINVAL;
+   }
+
+   nomap = of_get_flat_dt_prop(node, no-map, NULL) != NULL;
+
+   while (len  0) {
+   base = dt_mem_next_cell(dt_root_addr_cells, prop);
+   size = dt_mem_next_cell(dt_root_size_cells, prop);
+
+   if (base  size 
+   early_init_dt_reserve_memory_arch(base, size, nomap) == 0)
+   pr_debug(Reserved memory: reserved region for node 
'%s': base %pa, size %ld MiB\n,
+   uname, base, (unsigned long)size / SZ_1M);
+   else
+   pr_info(Reserved memory: failed to reserve memory for 
node '%s': base %pa, size %ld MiB\n,
+   uname, base, (unsigned long)size / SZ_1M);
+
+   len -= t_len;
+   }
+   return 0;
+}
+
+static int __reserved_mem_check_root(unsigned long node)
+{
+   __be32 *prop;
+
+   prop = of_get_flat_dt_prop(node, #size-cells, NULL);
+   if (prop  be32_to_cpup(prop) != dt_root_size_cells)
+   return -EINVAL;
+
+   prop = of_get_flat_dt_prop(node, #address-cells, NULL);
+   if (prop  be32_to_cpup(prop) != dt_root_addr_cells)
+   return -EINVAL;
+
+   prop = of_get_flat_dt_prop(node, ranges, NULL);
+   if (!prop)
+   return -EINVAL;
+   return 0;
+}
+
+/**
+ * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory
+ */
+static int __init __fdt_scan_reserved_mem(unsigned long node, const char 
*uname,
+ int depth, void *data)
+{
+   static int found;
+   const char *status;
+
+   if (!found  depth == 1  strcmp(uname, reserved-memory) == 0) {
+   if (__reserved_mem_check_root(node) != 0) {
+   pr_err(Reserved memory: unsupported node format, 
ignoring\n);
+   /* break scan */
+   return 1;
+   }
+   found = 1;
+   /* scan next node */
+   return 0;
+   } else if (!found) {
+   /* scan next node */
+   return 0;
+   } else if (found  depth  2) {
+   /* scanning of /reserved-memory has been finished */
+   return 1;
+   }
+
+   status = of_get_flat_dt_prop(node, status, NULL);
+   if (status  strcmp(status, okay) != 0  strcmp(status, ok) != 0)
+   return 0;
+
+   __reserved_mem_reserve_reg(node, uname);
+
+   /* scan next node */
+   return 0;
+}
+
+/**
+ * early_init_fdt_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 (i.e. memblock) has been fully activated.
+ */
+void __init early_init_fdt_scan_reserved_mem(void)
+{
+   of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);
+}
+
+/**
  * of_scan_flat_dt - scan flattened tree blob and call callback on each.
  * @it: callback function
  * @data: context data pointer
@@ -856,6 +963,16 @@ void __init __weak

[PATCH v4 0/7] reserved-memory regions/CMA in devicetree, again

2014-02-20 Thread Marek Szyprowski
Hi all!

This is another quick update of the patches which add basic support for
dynamic allocation of memory reserved regions defined in device tree.

This time I hope I've really managed to address all the issues reported
by Grant Likely, see the change log for more details. As a bonus, I've
added support for ARM64 and PowerPC, as those architectures had quite
well defined place where early memory reservation can be done.

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.szyprow...@samsung.com
[2]: 
http://lkml.kernel.org/g/1381476448-14548-1-git-send-email-m.szyprow...@samsung.com
[3]: http://lkml.kernel.org/g/20131030134702.19b57c40...@trevor.secretlab.ca
[4]: http://thread.gmane.org/gmane.linux.documentation/19579

Changelog:

v4:
- dynamic allocations are processed after all static reservations has been
  done
- moved code for handling static reservations to drivers/of/fdt.c
- removed node matching by string comparison, now phandle values are used
  directly
- moved code for DMA and CMA handling directly to
  drivers/base/dma-{coherent,contiguous}.c
- added checks for proper #size-cells, #address-cells, ranges properties
  in /reserved-memory node
- even more code cleanup
- added init code for ARM64 and PowerPC

v3: http://article.gmane.org/gmane.linux.documentation/20169/
- refactored memory reservation code, created common code to parse reg, size,
  align, alloc-ranges properties
- added support for multiple tuples in 'reg' property
- memory is reserved regardless of presence of the driver for its compatible
- prepared arch specific hooks for memory reservation (defaults use memblock
  calls)
- removed node matching by string during device initialization
- CMA init code: added checks for required region alignment
- more code cleanup here and there

v2: http://thread.gmane.org/gmane.linux.documentation/19870/
- 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

Marek Szyprowski (6):
  drivers: of: add initialization code for reserved memory
  drivers: dma-coherent: add initialization from device tree
  drivers: dma-contiguous: add initialization from device tree
  arm: add support for reserved memory defined by device tree
  arm64: add support for reserved memory defined by device tree
  powerpc: add support for reserved memory defined by device tree

 .../bindings/reserved-memory/reserved-memory.txt   |  138 +
 arch/arm/Kconfig   |1 +
 arch/arm/mm/init.c |3 +
 arch/arm64/Kconfig |1 +
 arch/arm64/mm/init.c   |2 +
 arch/powerpc/Kconfig   |1 +
 arch/powerpc/kernel/prom.c |3 +
 drivers/base/dma-coherent.c|   41 +++
 drivers/base/dma-contiguous.c  |  130 +++--
 drivers/of/Kconfig |6 +
 drivers/of/Makefile|1 +
 drivers/of/fdt.c   |  145 ++
 drivers/of/of_reserved_mem.c   |  296 
 drivers/of/platform.c  |7 +
 include/asm-generic/vmlinux.lds.h  |   11 +
 include/linux/of_reserved_mem.h|   65 +
 16 files changed, 829 insertions(+), 22 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/reserved-memory/reserved

[PATCH v4 7/7] powerpc: add support for reserved memory defined by device tree

2014-02-20 Thread Marek Szyprowski
Enable reserved memory initialization from device tree.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 arch/powerpc/Kconfig   |1 +
 arch/powerpc/kernel/prom.c |3 +++
 2 files changed, 4 insertions(+)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 957bf344c0f5..3b6617fed8fc 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -90,6 +90,7 @@ config PPC
select BINFMT_ELF
select OF
select OF_EARLY_FLATTREE
+   select OF_RESERVED_MEM
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_TRACER
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index f58c0d3aaeb4..b814262a2048 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -33,6 +33,7 @@
 #include linux/irq.h
 #include linux/memblock.h
 #include linux/of.h
+#include linux/of_reserved_mem.h
 
 #include asm/prom.h
 #include asm/rtas.h
@@ -588,6 +589,8 @@ static void __init early_reserve_mem_dt(void)
memblock_reserve(base, size);
}
}
+
+   early_init_fdt_scan_reserved_mem();
 }
 
 static void __init early_reserve_mem(void)
-- 
1.7.9.5

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


[PATCH v4 6/7] arm64: add support for reserved memory defined by device tree

2014-02-20 Thread Marek Szyprowski
Enable reserved memory initialization from device tree.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 arch/arm64/Kconfig   |1 +
 arch/arm64/mm/init.c |2 ++
 2 files changed, 3 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 27bbcfc7202a..6abf15407dca 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -43,6 +43,7 @@ config ARM64
select NO_BOOTMEM
select OF
select OF_EARLY_FLATTREE
+   select OF_RESERVED_MEM
select PERF_USE_VMALLOC
select POWER_RESET
select POWER_SUPPLY
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index d0b4c2efda90..447550d6bd9b 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -30,6 +30,7 @@
 #include linux/memblock.h
 #include linux/sort.h
 #include linux/of_fdt.h
+#include linux/of_reserved_mem.h
 #include linux/dma-contiguous.h
 
 #include asm/sections.h
@@ -160,6 +161,7 @@ void __init arm64_memblock_init(void)
memblock_reserve(base, size);
}
 
+   early_init_fdt_scan_reserved_mem();
dma_contiguous_reserve(0);
 
memblock_allow_resize();
-- 
1.7.9.5

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


[PATCH v4 3/7] drivers: dma-contiguous: add initialization from device tree

2014-02-20 Thread Marek Szyprowski
Refactor internal dma_contiguous_init_reserved_mem() function, which
creates CMA area from previously reserved memory region and add support
for handling 'shared-dma-pool' reserved-memory device tree nodes.

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/base/dma-contiguous.c |  130 ++---
 1 file changed, 108 insertions(+), 22 deletions(-)

diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 165c2c299e57..5dfcc3743d9b 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -182,6 +182,49 @@ static int __init cma_init_reserved_areas(void)
 core_initcall(cma_init_reserved_areas);
 
 /**
+ * dma_contiguous_init_reserved_mem() - reserve custom contiguous area
+ * @size: Size of the reserved area (in bytes),
+ * @base: Base address of the reserved area optional, use 0 for any
+ * @limit: End address of the reserved memory (optional, 0 for any).
+ * @res_cma: Pointer to store the created cma region.
+ *
+ * This function reserves memory from early allocator. It should be
+ * called by arch specific code once the early allocator (memblock or bootmem)
+ * has been activated and all other subsystems have already allocated/reserved
+ * memory. This function allows to create custom reserved areas for specific
+ * devices.
+ */
+static int __init dma_contiguous_init_reserved_mem(phys_addr_t size,
+   phys_addr_t base, struct cma **res_cma)
+{
+   struct cma *cma = cma_areas[cma_area_count];
+   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;
+
+   /* Sanitise input arguments */
+   alignment = PAGE_SIZE  max(MAX_ORDER - 1, pageblock_order);
+   if (ALIGN(base, alignment) != base || ALIGN(size, alignment) != size)
+   return -EINVAL;
+
+   cma-base_pfn = PFN_DOWN(base);
+   cma-count = size  PAGE_SHIFT;
+   *res_cma = cma;
+   cma_area_count++;
+
+   /* Architecture specific contiguous memory fixup. */
+   dma_contiguous_early_fixup(base, size);
+   return 0;
+}
+
+/**
  * dma_contiguous_reserve_area() - reserve custom contiguous area
  * @size: Size of the reserved area (in bytes),
  * @base: Base address of the reserved area optional, use 0 for any
@@ -197,7 +240,6 @@ core_initcall(cma_init_reserved_areas);
 int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
   phys_addr_t limit, struct cma **res_cma)
 {
-   struct cma *cma = cma_areas[cma_area_count];
phys_addr_t alignment;
int ret = 0;
 
@@ -205,12 +247,6 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, 
phys_addr_t base,
 (unsigned long)size, (unsigned long)base,
 (unsigned long)limit);
 
-   /* Sanity checks */
-   if (cma_area_count == ARRAY_SIZE(cma_areas)) {
-   pr_err(Not enough slots for CMA reserved regions!\n);
-   return -ENOSPC;
-   }
-
if (!size)
return -EINVAL;
 
@@ -241,21 +277,12 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, 
phys_addr_t base,
}
}
 
-   /*
-* Each reserved area must be initialised later, when more kernel
-* subsystems (like slab allocator) are available.
-*/
-   cma-base_pfn = PFN_DOWN(base);
-   cma-count = size  PAGE_SHIFT;
-   *res_cma = cma;
-   cma_area_count++;
-
-   pr_info(CMA: reserved %ld MiB at %08lx\n, (unsigned long)size / SZ_1M,
-   (unsigned long)base);
-
-   /* Architecture specific contiguous memory fixup. */
-   dma_contiguous_early_fixup(base, size);
-   return 0;
+   ret = dma_contiguous_init_reserved_mem(size, base, res_cma);
+   if (ret == 0) {
+   pr_info(CMA: reserved %ld MiB at %08lx\n,
+   (unsigned long)size / SZ_1M, (unsigned long)base);
+   return 0;
+   }
 err:
pr_err(CMA: failed to reserve %ld MiB\n, (unsigned long)size / SZ_1M);
return ret;
@@ -357,3 +384,62 @@ bool dma_release_from_contiguous(struct device *dev, 
struct page *pages,
 
return true;
 }
+
+/*
+ * 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 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

[PATCH v4 2/7] drivers: dma-coherent: add initialization from device tree

2014-02-20 Thread Marek Szyprowski
Add support for handling 'shared-dma-pool' reserved-memory device tree
nodes.

Based on previous code provided by Josh Cartwright jo...@codeaurora.org

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/base/dma-coherent.c |   41 +
 1 file changed, 41 insertions(+)

diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
index bc256b641027..2343ba5d6d43 100644
--- a/drivers/base/dma-coherent.c
+++ b/drivers/base/dma-coherent.c
@@ -218,3 +218,44 @@ 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 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)
+{
+   if (of_get_flat_dt_prop(node, reusable, NULL))
+   return -EINVAL;
+
+   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.7.9.5

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


[PATCH v4 5/7] arm: add support for reserved memory defined by device tree

2014-02-20 Thread Marek Szyprowski
Enable reserved memory initialization from device tree.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 arch/arm/Kconfig   |1 +
 arch/arm/mm/init.c |3 +++
 2 files changed, 4 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e25419817791..d0262bea8020 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1918,6 +1918,7 @@ config USE_OF
select IRQ_DOMAIN
select OF
select OF_EARLY_FLATTREE
+   select OF_RESERVED_MEM
help
  Include support for flattened device tree machine descriptions.
 
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 804d61566a53..eee55d75bbfa 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_fdt_scan_reserved_mem();
+
/*
 * 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 devicetree in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 4/7] of: document bindings for reserved-memory nodes

2014-02-20 Thread Marek Szyprowski
From: Grant Likely grant.lik...@linaro.org

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

Signed-off-by: Grant Likely grant.lik...@linaro.org
[joshc: Based on binding document proposed (in non-patch form) here:
 http://lkml.kernel.org/g/20131030134702.19b57c40...@trevor.secretlab.ca
 adapted to support #memory-region-cells]
Signed-off-by: Josh Cartwright jo...@codeaurora.org
Signed-off-by: Marek Szyprowski m.szyprow...@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 ..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@7200 and 64MiB in size),
+one dedicated

  1   2   >