aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2016-11-21 05:01:42 -0500
committerWill Deacon <will.deacon@arm.com>2016-11-29 10:57:45 -0500
commit2985b5210f4deb014bb976705d1c023eb973d1ed (patch)
tree58a36f28de4a360b70c36a6b00412aa8156758ed
parent846f0e9e74a034750123860804e247c13c5ee2ec (diff)
iommu/arm-smmu-v3: Split probe functions into DT/generic portions
Current ARM SMMUv3 probe functions intermingle HW and DT probing in the initialization functions to detect and programme the ARM SMMU v3 driver features. In order to allow probing the ARM SMMUv3 with other firmwares than DT, this patch splits the ARM SMMUv3 init functions into DT and HW specific portions so that other FW interfaces (ie ACPI) can reuse the HW probing functions and skip the DT portion accordingly. This patch implements no functional change, only code reshuffling. Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Reviewed-by: Tomasz Nowicki <tn@semihalf.com> Tested-by: Hanjun Guo <hanjun.guo@linaro.org> Tested-by: Tomasz Nowicki <tn@semihalf.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Hanjun Guo <hanjun.guo@linaro.org> Cc: Robin Murphy <robin.murphy@arm.com> Cc: Joerg Roedel <joro@8bytes.org> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--drivers/iommu/arm-smmu-v3.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 1406e1fd3847..d777d7e367bf 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2381,10 +2381,10 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
2381 return 0; 2381 return 0;
2382} 2382}
2383 2383
2384static int arm_smmu_device_probe(struct arm_smmu_device *smmu) 2384static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
2385{ 2385{
2386 u32 reg; 2386 u32 reg;
2387 bool coherent; 2387 bool coherent = smmu->features & ARM_SMMU_FEAT_COHERENCY;
2388 2388
2389 /* IDR0 */ 2389 /* IDR0 */
2390 reg = readl_relaxed(smmu->base + ARM_SMMU_IDR0); 2390 reg = readl_relaxed(smmu->base + ARM_SMMU_IDR0);
@@ -2436,13 +2436,9 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
2436 smmu->features |= ARM_SMMU_FEAT_HYP; 2436 smmu->features |= ARM_SMMU_FEAT_HYP;
2437 2437
2438 /* 2438 /*
2439 * The dma-coherent property is used in preference to the ID 2439 * The coherency feature as set by FW is used in preference to the ID
2440 * register, but warn on mismatch. 2440 * register, but warn on mismatch.
2441 */ 2441 */
2442 coherent = of_dma_is_coherent(smmu->dev->of_node);
2443 if (coherent)
2444 smmu->features |= ARM_SMMU_FEAT_COHERENCY;
2445
2446 if (!!(reg & IDR0_COHACC) != coherent) 2442 if (!!(reg & IDR0_COHACC) != coherent)
2447 dev_warn(smmu->dev, "IDR0.COHACC overridden by dma-coherent property (%s)\n", 2443 dev_warn(smmu->dev, "IDR0.COHACC overridden by dma-coherent property (%s)\n",
2448 coherent ? "true" : "false"); 2444 coherent ? "true" : "false");
@@ -2563,21 +2559,35 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
2563 return 0; 2559 return 0;
2564} 2560}
2565 2561
2566static int arm_smmu_device_dt_probe(struct platform_device *pdev) 2562static int arm_smmu_device_dt_probe(struct platform_device *pdev,
2563 struct arm_smmu_device *smmu)
2567{ 2564{
2568 int irq, ret;
2569 struct resource *res;
2570 struct arm_smmu_device *smmu;
2571 struct device *dev = &pdev->dev; 2565 struct device *dev = &pdev->dev;
2572 bool bypass = true;
2573 u32 cells; 2566 u32 cells;
2567 int ret = -EINVAL;
2574 2568
2575 if (of_property_read_u32(dev->of_node, "#iommu-cells", &cells)) 2569 if (of_property_read_u32(dev->of_node, "#iommu-cells", &cells))
2576 dev_err(dev, "missing #iommu-cells property\n"); 2570 dev_err(dev, "missing #iommu-cells property\n");
2577 else if (cells != 1) 2571 else if (cells != 1)
2578 dev_err(dev, "invalid #iommu-cells value (%d)\n", cells); 2572 dev_err(dev, "invalid #iommu-cells value (%d)\n", cells);
2579 else 2573 else
2580 bypass = false; 2574 ret = 0;
2575
2576 parse_driver_options(smmu);
2577
2578 if (of_dma_is_coherent(dev->of_node))
2579 smmu->features |= ARM_SMMU_FEAT_COHERENCY;
2580
2581 return ret;
2582}
2583
2584static int arm_smmu_device_probe(struct platform_device *pdev)
2585{
2586 int irq, ret;
2587 struct resource *res;
2588 struct arm_smmu_device *smmu;
2589 struct device *dev = &pdev->dev;
2590 bool bypass;
2581 2591
2582 smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL); 2592 smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
2583 if (!smmu) { 2593 if (!smmu) {
@@ -2614,10 +2624,11 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
2614 if (irq > 0) 2624 if (irq > 0)
2615 smmu->gerr_irq = irq; 2625 smmu->gerr_irq = irq;
2616 2626
2617 parse_driver_options(smmu); 2627 /* Set bypass mode according to firmware probing result */
2628 bypass = !!arm_smmu_device_dt_probe(pdev, smmu);
2618 2629
2619 /* Probe the h/w */ 2630 /* Probe the h/w */
2620 ret = arm_smmu_device_probe(smmu); 2631 ret = arm_smmu_device_hw_probe(smmu);
2621 if (ret) 2632 if (ret)
2622 return ret; 2633 return ret;
2623 2634
@@ -2679,7 +2690,7 @@ static struct platform_driver arm_smmu_driver = {
2679 .name = "arm-smmu-v3", 2690 .name = "arm-smmu-v3",
2680 .of_match_table = of_match_ptr(arm_smmu_of_match), 2691 .of_match_table = of_match_ptr(arm_smmu_of_match),
2681 }, 2692 },
2682 .probe = arm_smmu_device_dt_probe, 2693 .probe = arm_smmu_device_probe,
2683 .remove = arm_smmu_device_remove, 2694 .remove = arm_smmu_device_remove,
2684}; 2695};
2685 2696