+};
+
+/*
+ * SYSRAM contains areas that are not accessible by the
+ * kernel, such as the first 256K that is reserved for TZ.
+ * Accesses to those areas (including speculative accesses)
+ * trigger SErrors. As such we must map only the areas of
+ * SYSRAM specified in the device tree.
+ */
+static const struct sram_config tegra_sysram_config = {
+ .map_only_reserved = true,
+};
+
static const struct of_device_id sram_dt_ids[] = {
- { .compatible = "mmio-sram" },
- { .compatible = "atmel,sama5d2-securam", .data = atmel_securam_wait },
+ { .compatible = "mmio-sram", .data = &default_config },
+ { .compatible = "atmel,sama5d2-securam", .data = &atmel_securam_config },
+ { .compatible = "nvidia,tegra186-sysram", .data = &tegra_sysram_config },
+ { .compatible = "nvidia,tegra194-sysram", .data = &tegra_sysram_config },
{}
};
static int sram_probe(struct platform_device *pdev)
{
+ const struct sram_config *config;
struct sram_dev *sram;
int ret;
struct resource *res;
- int (*init_func)(void);
+
+ config = of_device_get_match_data(&pdev->dev);
sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL);
if (!sram)
return -ENOMEM;
sram->dev = &pdev->dev;
+ sram->no_memory_wc = of_property_read_bool(pdev->dev.of_node, "no-memory-wc");
+ sram->config = config;
+
+ if (!config->map_only_reserved) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (sram->no_memory_wc)
+ sram->virt_base = devm_ioremap_resource(&pdev->dev, res);
+ else
+ sram->virt_base = devm_ioremap_resource_wc(&pdev->dev, res);
+ if (IS_ERR(sram->virt_base)) {
+ dev_err(&pdev->dev, "could not map SRAM registers\n");
+ return PTR_ERR(sram->virt_base);
+ }
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (of_property_read_bool(pdev->dev.of_node, "no-memory-wc"))
- sram->virt_base = devm_ioremap_resource(&pdev->dev, res);
- else
- sram->virt_base = devm_ioremap_resource_wc(&pdev->dev, res);
- if (IS_ERR(sram->virt_base)) {
- dev_err(&pdev->dev, "could not map SRAM registers\n");
- return PTR_ERR(sram->virt_base);
+ 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->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))
sram->clk = NULL;
@@ -378,15 +424,15 @@ static int sram_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, sram);
- init_func = of_device_get_match_data(&pdev->dev);
- if (init_func) {
- ret = init_func();
+ if (config->init) {
+ ret = config->init();
if (ret)
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;
@@ -405,7 +451,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..d2058d8c8f1d 100644
--- a/drivers/misc/sram.h
+++ b/drivers/misc/sram.h
@@ -5,6 +5,11 @@
#ifndef __SRAM_H
#define __SRAM_H
+struct sram_config {
+ int (*init)(void);
+ bool map_only_reserved;
+};
+
struct sram_partition {
void __iomem *base;
@@ -15,8 +20,11 @@ struct sram_partition {
};
struct sram_dev {
+ const struct sram_config *config;
+
struct device *dev;
void __iomem *virt_base;
+ bool no_memory_wc;