aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/arm-smmu.c
diff options
context:
space:
mode:
authorRobin Murphy <robin.murphy@arm.com>2016-04-13 13:12:57 -0400
committerWill Deacon <will.deacon@arm.com>2016-05-03 13:23:01 -0400
commit67b65a3fb8e658d00ad1bb06e341f09b1f93a25c (patch)
treee585e1fd41b7c4b9c3bde03b85ec90da61d4c4af /drivers/iommu/arm-smmu.c
parent1bd37a6835bef0ecd2138cb42f9088fd890f9939 (diff)
iommu/arm-smmu: Differentiate specific implementations
As the inevitable reality of implementation-specific errata workarounds begin to accrue alongside our integration quirk handling, it's about time the driver had a decent way of keeping track. Extend the per-SMMU data so we can identify specific implementations in an efficient and firmware-agnostic manner. Acked-by: Tirumalesh Chalamarla <tchalamarla@caviumnetworks.com> Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'drivers/iommu/arm-smmu.c')
-rw-r--r--drivers/iommu/arm-smmu.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index e933679a3266..2d5f357de69c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -278,6 +278,10 @@ enum arm_smmu_arch_version {
278 ARM_SMMU_V2, 278 ARM_SMMU_V2,
279}; 279};
280 280
281enum arm_smmu_implementation {
282 GENERIC_SMMU,
283};
284
281struct arm_smmu_smr { 285struct arm_smmu_smr {
282 u8 idx; 286 u8 idx;
283 u16 mask; 287 u16 mask;
@@ -315,6 +319,7 @@ struct arm_smmu_device {
315#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0) 319#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0)
316 u32 options; 320 u32 options;
317 enum arm_smmu_arch_version version; 321 enum arm_smmu_arch_version version;
322 enum arm_smmu_implementation model;
318 323
319 u32 num_context_banks; 324 u32 num_context_banks;
320 u32 num_s2_context_banks; 325 u32 num_s2_context_banks;
@@ -1735,13 +1740,24 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
1735 return 0; 1740 return 0;
1736} 1741}
1737 1742
1743struct arm_smmu_match_data {
1744 enum arm_smmu_arch_version version;
1745 enum arm_smmu_implementation model;
1746};
1747
1748#define ARM_SMMU_MATCH_DATA(name, ver, imp) \
1749static struct arm_smmu_match_data name = { .version = ver, .model = imp }
1750
1751ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU);
1752ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU);
1753
1738static const struct of_device_id arm_smmu_of_match[] = { 1754static const struct of_device_id arm_smmu_of_match[] = {
1739 { .compatible = "arm,smmu-v1", .data = (void *)ARM_SMMU_V1 }, 1755 { .compatible = "arm,smmu-v1", .data = &smmu_generic_v1 },
1740 { .compatible = "arm,smmu-v2", .data = (void *)ARM_SMMU_V2 }, 1756 { .compatible = "arm,smmu-v2", .data = &smmu_generic_v2 },
1741 { .compatible = "arm,mmu-400", .data = (void *)ARM_SMMU_V1 }, 1757 { .compatible = "arm,mmu-400", .data = &smmu_generic_v1 },
1742 { .compatible = "arm,mmu-401", .data = (void *)ARM_SMMU_V1 }, 1758 { .compatible = "arm,mmu-401", .data = &smmu_generic_v1 },
1743 { .compatible = "arm,mmu-500", .data = (void *)ARM_SMMU_V2 }, 1759 { .compatible = "arm,mmu-500", .data = &smmu_generic_v2 },
1744 { .compatible = "cavium,smmu-v2", .data = (void *)ARM_SMMU_V2 }, 1760 { .compatible = "cavium,smmu-v2", .data = &smmu_generic_v2 },
1745 { }, 1761 { },
1746}; 1762};
1747MODULE_DEVICE_TABLE(of, arm_smmu_of_match); 1763MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
@@ -1749,6 +1765,7 @@ MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
1749static int arm_smmu_device_dt_probe(struct platform_device *pdev) 1765static int arm_smmu_device_dt_probe(struct platform_device *pdev)
1750{ 1766{
1751 const struct of_device_id *of_id; 1767 const struct of_device_id *of_id;
1768 const struct arm_smmu_match_data *data;
1752 struct resource *res; 1769 struct resource *res;
1753 struct arm_smmu_device *smmu; 1770 struct arm_smmu_device *smmu;
1754 struct device *dev = &pdev->dev; 1771 struct device *dev = &pdev->dev;
@@ -1764,7 +1781,9 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
1764 smmu->dev = dev; 1781 smmu->dev = dev;
1765 1782
1766 of_id = of_match_node(arm_smmu_of_match, dev->of_node); 1783 of_id = of_match_node(arm_smmu_of_match, dev->of_node);
1767 smmu->version = (enum arm_smmu_arch_version)of_id->data; 1784 data = of_id->data;
1785 smmu->version = data->version;
1786 smmu->model = data->model;
1768 1787
1769 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1788 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1770 smmu->base = devm_ioremap_resource(dev, res); 1789 smmu->base = devm_ioremap_resource(dev, res);