lkml.org 
[lkml]   [2012]   [Apr]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 1/3] iommu/tegra: smmu: Reserve SMMU reg regions precisely
Date
SMMU register regions are located into 3 blocks discontiguously.

Get them and reserve each region respectively. This allows other
module to use/reserve other register regions between SMMU register
blocks.

Signed-off-by: Hiroshi DOYU <hdoyu@nvidia.com>
---
drivers/iommu/tegra-smmu.c | 44 ++++++++++++++++++++++++++++++++++++--------
1 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index de9fafe..90bbf07 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -173,6 +173,8 @@
#define SMMU_ASID_DISABLE 0
#define SMMU_ASID_ASID(n) ((n) & ~SMMU_ASID_ENABLE(0))

+#define NUM_SMMU_REG_BLOCKS 3
+
#define smmu_client_enable_hwgrp(c, m) smmu_client_set_hwgrp(c, m, 1)
#define smmu_client_disable_hwgrp(c) smmu_client_set_hwgrp(c, 0, 0)
#define __smmu_client_enable_hwgrp(c, m) __smmu_client_set_hwgrp(c, m, 1)
@@ -866,7 +868,7 @@ static int tegra_smmu_resume(struct device *dev)
static int tegra_smmu_probe(struct platform_device *pdev)
{
struct smmu_device *smmu;
- struct resource *regs, *window;
+ struct resource *res[NUM_SMMU_REG_BLOCKS], *window;
struct device *dev = &pdev->dev;
int i, err = 0;

@@ -875,9 +877,25 @@ static int tegra_smmu_probe(struct platform_device *pdev)

BUILD_BUG_ON(PAGE_SHIFT != SMMU_PAGE_SHIFT);

- regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- window = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!regs || !window) {
+ for (i = 0; i < ARRAY_SIZE(res); i++) {
+ res[i] = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ if (!res[i])
+ return -ENODEV;
+
+ res[i] = devm_request_mem_region(&pdev->dev, res[i]->start,
+ resource_size(res[i]),
+ dev_name(&pdev->dev));
+ if (res[i])
+ continue;
+
+ while (--i >= 0)
+ devm_release_mem_region(&pdev->dev, res[i]->start,
+ resource_size(res[i]));
+ return -EIO;
+ }
+
+ window = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+ if (!window) {
dev_err(dev, "No SMMU resources\n");
return -ENODEV;
}
@@ -892,7 +910,8 @@ static int tegra_smmu_probe(struct platform_device *pdev)
smmu->num_as = SMMU_NUM_ASIDS;
smmu->iovmm_base = (unsigned long)window->start;
smmu->page_count = resource_size(window) >> SMMU_PAGE_SHIFT;
- smmu->regs = devm_ioremap(dev, regs->start, resource_size(regs));
+ smmu->regs = devm_ioremap(dev, res[0]->start,
+ res[2]->end - res[0]->start + 1);
if (!smmu->regs) {
dev_err(dev, "failed to remap SMMU registers\n");
err = -ENXIO;
@@ -905,7 +924,7 @@ static int tegra_smmu_probe(struct platform_device *pdev)
smmu->asid_security = 0;

smmu->as = devm_kzalloc(dev,
- sizeof(smmu->as[0]) * smmu->num_as, GFP_KERNEL);
+ sizeof(smmu->as[0]) * smmu->num_as, GFP_KERNEL);
if (!smmu->as) {
dev_err(dev, "failed to allocate smmu_as\n");
err = -ENOMEM;
@@ -950,6 +969,9 @@ fail:
devm_kfree(dev, smmu->as);
}
devm_kfree(dev, smmu);
+ for (i = 0; i < ARRAY_SIZE(res); i++)
+ devm_release_mem_region(&pdev->dev, res[i]->start,
+ resource_size(res[i]));
return err;
}

@@ -957,12 +979,11 @@ static int tegra_smmu_remove(struct platform_device *pdev)
{
struct smmu_device *smmu = platform_get_drvdata(pdev);
struct device *dev = smmu->dev;
+ int i;

smmu_write(smmu, SMMU_CONFIG_DISABLE, SMMU_CONFIG);
platform_set_drvdata(pdev, NULL);
if (smmu->as) {
- int i;
-
for (i = 0; i < smmu->num_as; i++)
free_pdir(&smmu->as[i]);
devm_kfree(dev, smmu->as);
@@ -973,6 +994,13 @@ static int tegra_smmu_remove(struct platform_device *pdev)
devm_iounmap(dev, smmu->regs);
devm_kfree(dev, smmu);
smmu_handle = NULL;
+ for (i = 0; i < NUM_SMMU_REG_BLOCKS; i++) {
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ devm_release_mem_region(&pdev->dev, res->start,
+ resource_size(res));
+ }
return 0;
}

--
1.7.5.4


\
 
 \ /
  Last update: 2012-04-23 14:01    [W:0.528 / U:0.000 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site