linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: heiko@sntech.de (Heiko Stübner)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 2/6] misc: sram: add ability to mark sram sections as reserved
Date: Tue, 25 Jun 2013 10:47:12 +0200	[thread overview]
Message-ID: <201306251047.12899.heiko@sntech.de> (raw)
In-Reply-To: <201306251046.04873.heiko@sntech.de>

Some SoCs need parts of their sram for special purposes. So while being part
of the periphal, it should not be part of the genpool controlling the sram.

Threfore add an option mmio-sram-reserved to keep arbitary portions of the
sram from being part of the pool.

Suggested-by: Rob Herring <robherring2@gmail.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 Documentation/devicetree/bindings/misc/sram.txt |    8 +++
 drivers/misc/sram.c                             |   86 +++++++++++++++++++++--
 2 files changed, 88 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/misc/sram.txt
index 4d0a00e..eae080e 100644
--- a/Documentation/devicetree/bindings/misc/sram.txt
+++ b/Documentation/devicetree/bindings/misc/sram.txt
@@ -8,9 +8,17 @@ Required properties:
 
 - reg : SRAM iomem address range
 
+Optional properties:
+
+- mmio-sram-reserved: ordered list of reserved chunks inside the sram that
+  should not become part of the genalloc pool.
+  Format is <base size>, <base size>, ...; with base being relative to the
+  reg property base.
+
 Example:
 
 sram: sram at 5c000000 {
 	compatible = "mmio-sram";
 	reg = <0x5c000000 0x40000>; /* 256 KiB SRAM at address 0x5c000000 */
+	mmio-sram-reserved = <0x0 0x100>; /* reserve 0x5c000000-0x5c000100 */
 };
diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c
index afe66571..5fccbe3 100644
--- a/drivers/misc/sram.c
+++ b/drivers/misc/sram.c
@@ -42,6 +42,8 @@ static int sram_probe(struct platform_device *pdev)
 	struct sram_dev *sram;
 	struct resource *res;
 	unsigned long size;
+	const __be32 *reserved_list = NULL;
+	int reserved_size = 0;
 	int ret;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -65,12 +67,89 @@ static int sram_probe(struct platform_device *pdev)
 	if (!sram->pool)
 		return -ENOMEM;
 
-	ret = gen_pool_add_virt(sram->pool, (unsigned long)virt_base,
-				res->start, size, -1);
-	if (ret < 0) {
-		if (sram->clk)
-			clk_disable_unprepare(sram->clk);
-		return ret;
+	if (pdev->dev.of_node) {
+		reserved_list = of_get_property(pdev->dev.of_node,
+						"mmio-sram-reserved",
+						&reserved_size);
+		if (reserved_list) {
+			reserved_size /= sizeof(*reserved_list);
+			if (!reserved_size || reserved_size % 2) {
+				dev_warn(&pdev->dev, "wrong number of arguments in mmio-sram-reserved\n");
+				reserved_list = NULL;
+			}
+		}
+	}
+
+	if (!reserved_list) {
+		ret = gen_pool_add_virt(sram->pool, (unsigned long)virt_base,
+					res->start, size, -1);
+		if (ret < 0) {
+			if (sram->clk)
+				clk_disable_unprepare(sram->clk);
+			return ret;
+		}
+	} else {
+		unsigned int cur_start = 0;
+		unsigned int cur_size;
+		unsigned int rstart;
+		unsigned int rsize;
+		int i;
+
+		for (i = 0; i < reserved_size; i += 2) {
+			/* get the next reserved block */
+			rstart = be32_to_cpu(*reserved_list++);
+			rsize = be32_to_cpu(*reserved_list++);
+
+			/* catch unsorted list entries */
+			if (rstart < cur_start) {
+				dev_err(&pdev->dev, "unsorted reserved list (0x%x before current 0x%x)\n",
+					rstart, cur_start);
+				if (sram->clk)
+					clk_disable_unprepare(sram->clk);
+				return -EINVAL;
+			}
+
+			dev_dbg(&pdev->dev, "found reserved block 0x%x-0x%x\n",
+				 rstart, rstart + rsize);
+
+			/* current start is in a reserved block */
+			if (rstart <= cur_start) {
+				cur_start = rstart + rsize;
+				continue;
+			}
+
+			/*
+			 * allocate the space between the current starting
+			 * address and the following reserved block
+			 */
+			cur_size = rstart - cur_start;
+
+			dev_dbg(&pdev->dev, "adding chunk 0x%x-0x%x\n",
+				 cur_start, cur_start + cur_size);
+			ret = gen_pool_add_virt(sram->pool,
+					(unsigned long)virt_base + cur_start,
+					res->start + cur_start, cur_size, -1);
+			if (ret < 0) {
+				if (sram->clk)
+					clk_disable_unprepare(sram->clk);
+				return ret;
+			}
+
+			/* next allocation after this reserved block */
+			cur_start = rstart + rsize;
+		}
+
+		/* allocate the space after the last reserved block */
+		if (cur_start < size) {
+			cur_size = size - cur_start;
+
+			dev_dbg(&pdev->dev, "adding chunk 0x%x-0x%x\n",
+				 cur_start, cur_start + cur_size);
+			ret = gen_pool_add_virt(sram->pool,
+					(unsigned long)virt_base + cur_start,
+					res->start + cur_start, cur_size, -1);
+		}
+
 	}
 
 	platform_set_drvdata(pdev, sram);
-- 
1.7.10.4

  parent reply	other threads:[~2013-06-25  8:47 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-25  8:46 [PATCH v2 0/6] ARM: rockchip: add smp functionality Heiko Stübner
2013-06-25  8:46 ` [PATCH v2 1/6] misc: sram: fix error path in sram_probe Heiko Stübner
2013-06-25  9:04   ` Philipp Zabel
2013-07-04 14:34     ` Heiko Stübner
2013-07-04 15:41       ` Philipp Zabel
2013-06-25  8:47 ` Heiko Stübner [this message]
2013-06-25 10:17   ` [PATCH v2 2/6] misc: sram: add ability to mark sram sections as reserved Philipp Zabel
2013-06-26  9:18     ` Heiko Stübner
2013-06-26 10:09       ` Philipp Zabel
2013-06-25  8:47 ` [PATCH v2 3/6] ARM: rockchip: add snoop-control-unit Heiko Stübner
2013-06-25  8:48 ` [PATCH v2 4/6] ARM: rockchip: add sram dt nodes and documentation Heiko Stübner
2013-06-25  8:48 ` [PATCH v2 5/6] ARM: rockchip: add power-management-unit dt node Heiko Stübner
2013-06-25  8:49 ` [PATCH v2 6/6] ARM: rockchip: add smp bringup code Heiko Stübner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201306251047.12899.heiko@sntech.de \
    --to=heiko@sntech.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).