aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2014-06-25 06:29:12 -0400
committerWill Deacon <will.deacon@arm.com>2014-07-03 10:50:22 -0400
commit44680eedf9409daf0fed618ae101f35d1f83d1a4 (patch)
tree5951a5e3af529803ead15a7885a12f0008fabb70
parentd0948945638635487111d0851218080e81de5104 (diff)
iommu/arm-smmu: remove support for chained SMMUs
The ARM SMMU driver has supported chained SMMUs (i.e. SMMUs connected back-to-back in series) via the smmu-parent property in device tree. This was in anticipation of somebody building such a configuration, however that seems not to be the case. This patch removes the unused chained SMMU hack from the driver. We can consider adding it back later if somebody decided they need it, but for the time being it's just pointless mess that we're carrying in mainline. Removal of the feature also makes migration to the generic IOMMU bindings easier. Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--Documentation/devicetree/bindings/iommu/arm,smmu.txt6
-rw-r--r--drivers/iommu/arm-smmu.c263
2 files changed, 77 insertions, 192 deletions
diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index f284b99402bc..2d0f7cd867ea 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -42,12 +42,6 @@ conditions.
42 42
43** System MMU optional properties: 43** System MMU optional properties:
44 44
45- smmu-parent : When multiple SMMUs are chained together, this
46 property can be used to provide a phandle to the
47 parent SMMU (that is the next SMMU on the path going
48 from the mmu-masters towards memory) node for this
49 SMMU.
50
51- calxeda,smmu-secure-config-access : Enable proper handling of buggy 45- calxeda,smmu-secure-config-access : Enable proper handling of buggy
52 implementations that always use secure access to 46 implementations that always use secure access to
53 SMMU configuration registers. In this case non-secure 47 SMMU configuration registers. In this case non-secure
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 3ae50be49269..2961b8c474eb 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -333,28 +333,17 @@ struct arm_smmu_smr {
333struct arm_smmu_master_cfg { 333struct arm_smmu_master_cfg {
334 int num_streamids; 334 int num_streamids;
335 u16 streamids[MAX_MASTER_STREAMIDS]; 335 u16 streamids[MAX_MASTER_STREAMIDS];
336
337 /*
338 * We only need to allocate these on the root SMMU, as we
339 * configure unmatched streams to bypass translation.
340 */
341 struct arm_smmu_smr *smrs; 336 struct arm_smmu_smr *smrs;
342}; 337};
343 338
344struct arm_smmu_master { 339struct arm_smmu_master {
345 struct device_node *of_node; 340 struct device_node *of_node;
346
347 /*
348 * The following is specific to the master's position in the
349 * SMMU chain.
350 */
351 struct rb_node node; 341 struct rb_node node;
352 struct arm_smmu_master_cfg cfg; 342 struct arm_smmu_master_cfg cfg;
353}; 343};
354 344
355struct arm_smmu_device { 345struct arm_smmu_device {
356 struct device *dev; 346 struct device *dev;
357 struct device_node *parent_of_node;
358 347
359 void __iomem *base; 348 void __iomem *base;
360 unsigned long size; 349 unsigned long size;
@@ -392,7 +381,6 @@ struct arm_smmu_device {
392}; 381};
393 382
394struct arm_smmu_cfg { 383struct arm_smmu_cfg {
395 struct arm_smmu_device *smmu;
396 u8 cbndx; 384 u8 cbndx;
397 u8 irptndx; 385 u8 irptndx;
398 u32 cbar; 386 u32 cbar;
@@ -404,15 +392,8 @@ struct arm_smmu_cfg {
404#define ARM_SMMU_CB_VMID(cfg) ((cfg)->cbndx + 1) 392#define ARM_SMMU_CB_VMID(cfg) ((cfg)->cbndx + 1)
405 393
406struct arm_smmu_domain { 394struct arm_smmu_domain {
407 /* 395 struct arm_smmu_device *smmu;
408 * A domain can span across multiple, chained SMMUs and requires 396 struct arm_smmu_cfg cfg;
409 * all devices within the domain to follow the same translation
410 * path.
411 */
412 struct arm_smmu_device *leaf_smmu;
413 struct arm_smmu_cfg root_cfg;
414 phys_addr_t output_mask;
415
416 spinlock_t lock; 397 spinlock_t lock;
417}; 398};
418 399
@@ -546,59 +527,20 @@ static int register_smmu_master(struct arm_smmu_device *smmu,
546 return insert_smmu_master(smmu, master); 527 return insert_smmu_master(smmu, master);
547} 528}
548 529
549static struct arm_smmu_device *find_parent_smmu(struct arm_smmu_device *smmu) 530static struct arm_smmu_device *find_smmu_for_device(struct device *dev)
550{ 531{
551 struct arm_smmu_device *parent; 532 struct arm_smmu_device *smmu;
552
553 if (!smmu->parent_of_node)
554 return NULL;
555
556 spin_lock(&arm_smmu_devices_lock);
557 list_for_each_entry(parent, &arm_smmu_devices, list)
558 if (parent->dev->of_node == smmu->parent_of_node)
559 goto out_unlock;
560
561 parent = NULL;
562 dev_warn(smmu->dev,
563 "Failed to find SMMU parent despite parent in DT\n");
564out_unlock:
565 spin_unlock(&arm_smmu_devices_lock);
566 return parent;
567}
568
569static struct arm_smmu_device *find_parent_smmu_for_device(struct device *dev)
570{
571 struct arm_smmu_device *child, *parent, *smmu;
572 struct arm_smmu_master *master = NULL; 533 struct arm_smmu_master *master = NULL;
573 struct device_node *dev_node = dev_get_master_dev(dev)->of_node; 534 struct device_node *dev_node = dev_get_master_dev(dev)->of_node;
574 535
575 spin_lock(&arm_smmu_devices_lock); 536 spin_lock(&arm_smmu_devices_lock);
576 list_for_each_entry(parent, &arm_smmu_devices, list) { 537 list_for_each_entry(smmu, &arm_smmu_devices, list) {
577 smmu = parent;
578
579 /* Try to find a child of the current SMMU. */
580 list_for_each_entry(child, &arm_smmu_devices, list) {
581 if (child->parent_of_node == parent->dev->of_node) {
582 /* Does the child sit above our master? */
583 master = find_smmu_master(child, dev_node);
584 if (master) {
585 smmu = NULL;
586 break;
587 }
588 }
589 }
590
591 /* We found some children, so keep searching. */
592 if (!smmu) {
593 master = NULL;
594 continue;
595 }
596
597 master = find_smmu_master(smmu, dev_node); 538 master = find_smmu_master(smmu, dev_node);
598 if (master) 539 if (master)
599 break; 540 break;
600 } 541 }
601 spin_unlock(&arm_smmu_devices_lock); 542 spin_unlock(&arm_smmu_devices_lock);
543
602 return master ? smmu : NULL; 544 return master ? smmu : NULL;
603} 545}
604 546
@@ -639,9 +581,10 @@ static void arm_smmu_tlb_sync(struct arm_smmu_device *smmu)
639 } 581 }
640} 582}
641 583
642static void arm_smmu_tlb_inv_context(struct arm_smmu_cfg *cfg) 584static void arm_smmu_tlb_inv_context(struct arm_smmu_domain *smmu_domain)
643{ 585{
644 struct arm_smmu_device *smmu = cfg->smmu; 586 struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
587 struct arm_smmu_device *smmu = smmu_domain->smmu;
645 void __iomem *base = ARM_SMMU_GR0(smmu); 588 void __iomem *base = ARM_SMMU_GR0(smmu);
646 bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS; 589 bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS;
647 590
@@ -665,11 +608,11 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
665 unsigned long iova; 608 unsigned long iova;
666 struct iommu_domain *domain = dev; 609 struct iommu_domain *domain = dev;
667 struct arm_smmu_domain *smmu_domain = domain->priv; 610 struct arm_smmu_domain *smmu_domain = domain->priv;
668 struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg; 611 struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
669 struct arm_smmu_device *smmu = root_cfg->smmu; 612 struct arm_smmu_device *smmu = smmu_domain->smmu;
670 void __iomem *cb_base; 613 void __iomem *cb_base;
671 614
672 cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, root_cfg->cbndx); 615 cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
673 fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR); 616 fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR);
674