Some SRAM kernel users may be interested in SRAM’s reserved regions
only, though a bigger SRAM is available on the platform. Add an
optional flag 'reserved-only' which allows to ioremap reserved regions
only. Rest of SRAM is not remapped. ioremap type is selected depending
upon no-memory-wc as usual.

Signed-off-by: Mian Yousaf Kaukab <[email protected]>
---
*Tested only on Jetson TX2. Jetson AGX Xavier is untested.*

 drivers/misc/sram.c | 73 ++++++++++++++++++++++++++++++++++-----------
 drivers/misc/sram.h |  3 ++
 2 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c
index 6c1a23cb3e8c..44e459f39e22 100644
--- a/drivers/misc/sram.c
+++ b/drivers/misc/sram.c
@@ -97,7 +97,7 @@ static int sram_add_partition(struct sram_dev *sram, struct 
sram_reserve *block,
        struct sram_partition *part = &sram->partition[sram->partitions];
 
        mutex_init(&part->lock);
-       part->base = sram->virt_base + block->start;
+       part->base = block->virt_start;
 
        if (block->pool) {
                ret = sram_add_pool(sram, block, start, part);
@@ -153,6 +153,25 @@ static int sram_reserve_cmp(void *priv, struct list_head 
*a,
        return ra->start - rb->start;
 }
 
+static int sram_remap_resource(struct sram_dev *sram,
+               struct resource *res, void __iomem **virt)
+{
+       void __iomem *addr;
+
+       if (sram->no_memory_wc)
+               addr = devm_ioremap_resource(sram->dev, res);
+       else
+               addr = devm_ioremap_resource_wc(sram->dev, res);
+
+       if (IS_ERR(addr)) {
+               dev_err(sram->dev, "could not map SRAM region\n");
+               return PTR_ERR(addr);
+       }
+
+       *virt = addr;
+       return 0;
+}
+
 static int sram_reserve_regions(struct sram_dev *sram, struct resource *res)
 {
        struct device_node *np = sram->dev->of_node, *child;
@@ -239,6 +258,16 @@ static int sram_reserve_regions(struct sram_dev *sram, 
struct resource *res)
                                block->start, block->start + block->size);
                }
 
+               /* ioremap reserved block as whole sram is not remapped */
+               if (sram->reserved_only) {
+                       ret = sram_remap_resource(sram, &child_res,
+                                       &block->virt_start);
+                       if (ret)
+                               goto err_chunks;
+               } else {
+                       block->virt_start = sram->virt_base + block->start;
+               }
+
                block++;
        }
        child = NULL;
@@ -282,8 +311,11 @@ static int sram_reserve_regions(struct sram_dev *sram, 
struct resource *res)
                        }
                }
 
-               /* current start is in a reserved block, so continue after it */
-               if (block->start == cur_start) {
+               /*
+                * Current start is in a reserved block, so continue after it.
+                * Or if only using reserved blocks
+                */
+               if (block->start == cur_start || sram->reserved_only) {
                        cur_start = block->start + block->size;
                        continue;
                }
@@ -342,6 +374,7 @@ static int sram_probe(struct platform_device *pdev)
        struct sram_dev *sram;
        int ret;
        int (*init_func)(void);
+       struct resource *res;
 
        sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL);
        if (!sram)
@@ -349,19 +382,22 @@ static int sram_probe(struct platform_device *pdev)
 
        sram->dev = &pdev->dev;
 
-       if (of_property_read_bool(pdev->dev.of_node, "no-memory-wc"))
-               sram->virt_base = devm_platform_ioremap_resource(pdev, 0);
-       else
-               sram->virt_base = devm_platform_ioremap_resource_wc(pdev, 0);
-       if (IS_ERR(sram->virt_base)) {
-               dev_err(&pdev->dev, "could not map SRAM registers\n");
-               return PTR_ERR(sram->virt_base);
-       }
+       sram->no_memory_wc =
+               of_property_read_bool(pdev->dev.of_node, "no-memory-wc");
+       sram->reserved_only =
+               of_property_read_bool(pdev->dev.of_node, "reserved-only");
 
-       sram->pool = devm_gen_pool_create(sram->dev, ilog2(SRAM_GRANULARITY),
-                                         NUMA_NO_NODE, NULL);
-       if (IS_ERR(sram->pool))
-               return PTR_ERR(sram->pool);
+       if (!sram->reserved_only) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+               ret = sram_remap_resource(sram, res, &sram->virt_base);
+               if (ret)
+                       return ret;
+
+               sram->pool = devm_gen_pool_create(sram->dev,
+                               ilog2(SRAM_GRANULARITY), NUMA_NO_NODE, NULL);
+               if (IS_ERR(sram->pool))
+                       return PTR_ERR(sram->pool);
+       }
 
        sram->clk = devm_clk_get(sram->dev, NULL);
        if (IS_ERR(sram->clk))
@@ -383,8 +419,9 @@ static int sram_probe(struct platform_device *pdev)
                        goto err_free_partitions;
        }
 
-       dev_dbg(sram->dev, "SRAM pool: %zu KiB @ 0x%p\n",
-               gen_pool_size(sram->pool) / 1024, sram->virt_base);
+       if (sram->pool)
+               dev_dbg(sram->dev, "SRAM pool: %zu KiB @ 0x%p\n",
+                       gen_pool_size(sram->pool) / 1024, sram->virt_base);
 
        return 0;
 
@@ -403,7 +440,7 @@ static int sram_remove(struct platform_device *pdev)
 
        sram_free_partitions(sram);
 
-       if (gen_pool_avail(sram->pool) < gen_pool_size(sram->pool))
+       if (sram->pool && gen_pool_avail(sram->pool) < 
gen_pool_size(sram->pool))
                dev_err(sram->dev, "removed while SRAM allocated\n");
 
        if (sram->clk)
diff --git a/drivers/misc/sram.h b/drivers/misc/sram.h
index 9c1d21ff7347..a485fa29458b 100644
--- a/drivers/misc/sram.h
+++ b/drivers/misc/sram.h
@@ -23,6 +23,8 @@ struct sram_dev {
 
        struct sram_partition *partition;
        u32 partitions;
+       bool no_memory_wc;
+       bool reserved_only;
 };
 
 struct sram_reserve {
@@ -33,6 +35,7 @@ struct sram_reserve {
        bool pool;
        bool protect_exec;
        const char *label;
+       void __iomem *virt_start;
 };
 
 #ifdef CONFIG_SRAM_EXEC
-- 
2.25.0

Reply via email to