@@ -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)
@@ -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
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 <ykaukab@suse.de> --- *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(-)