All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] iommu/tegra: smmu: Reserve SMMU reg regions precisely
@ 2012-04-23 11:58 ` Hiroshi DOYU
  0 siblings, 0 replies; 14+ messages in thread
From: Hiroshi DOYU @ 2012-04-23 11:58 UTC (permalink / raw)
  To: hdoyu-DDmLM1+adcrQT0dZR+AlfA
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Joerg Roedel, Thierry Reding,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

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-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 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

^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2012-04-24 19:34 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-23 11:58 [PATCH 1/3] iommu/tegra: smmu: Reserve SMMU reg regions precisely Hiroshi DOYU
2012-04-23 11:58 ` Hiroshi DOYU
2012-04-23 11:58 ` [PATCH 2/3] iommu/tegra: smmu: Add device tree support for SMMU Hiroshi DOYU
2012-04-23 18:27   ` Stephen Warren
2012-04-24  8:59     ` Hiroshi Doyu
2012-04-24  8:59       ` Hiroshi Doyu
     [not found] ` <1335182340-17237-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-04-23 11:58   ` [PATCH 3/3] arm/dts: Tegra30: " Hiroshi DOYU
2012-04-23 11:58     ` Hiroshi DOYU
2012-04-23 11:58     ` Hiroshi DOYU
     [not found]     ` <1335182340-17237-3-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-04-24 19:34       ` Stephen Warren
2012-04-24 19:34         ` Stephen Warren
2012-04-24 19:34         ` Stephen Warren
2012-04-23 18:23   ` [PATCH 1/3] iommu/tegra: smmu: Reserve SMMU reg regions precisely Stephen Warren
2012-04-23 18:23     ` Stephen Warren

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.