Skip to content

Commit 9648cbc

Browse files
committed
iommu/arm-smmu: Make use of the iommu_register interface
Also add the smmu devices to sysfs. Signed-off-by: Joerg Roedel <[email protected]>
1 parent c73e1ac commit 9648cbc

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

drivers/iommu/arm-smmu-v3.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,9 @@ struct arm_smmu_device {
616616
unsigned int sid_bits;
617617

618618
struct arm_smmu_strtab_cfg strtab_cfg;
619+
620+
/* IOMMU core code handle */
621+
struct iommu_device iommu;
619622
};
620623

621624
/* SMMU private data for each master */
@@ -1795,8 +1798,10 @@ static int arm_smmu_add_device(struct device *dev)
17951798
}
17961799

17971800
group = iommu_group_get_for_dev(dev);
1798-
if (!IS_ERR(group))
1801+
if (!IS_ERR(group)) {
17991802
iommu_group_put(group);
1803+
iommu_device_link(&smmu->iommu, dev);
1804+
}
18001805

18011806
return PTR_ERR_OR_ZERO(group);
18021807
}
@@ -1805,14 +1810,17 @@ static void arm_smmu_remove_device(struct device *dev)
18051810
{
18061811
struct iommu_fwspec *fwspec = dev->iommu_fwspec;
18071812
struct arm_smmu_master_data *master;
1813+
struct arm_smmu_device *smmu;
18081814

18091815
if (!fwspec || fwspec->ops != &arm_smmu_ops)
18101816
return;
18111817

18121818
master = fwspec->iommu_priv;
1819+
smmu = master->smmu;
18131820
if (master && master->ste.valid)
18141821
arm_smmu_detach_dev(dev);
18151822
iommu_group_remove_device(dev);
1823+
iommu_device_unlink(&smmu->iommu, dev);
18161824
kfree(master);
18171825
iommu_fwspec_free(dev);
18181826
}
@@ -2613,6 +2621,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
26132621
{
26142622
int irq, ret;
26152623
struct resource *res;
2624+
resource_size_t ioaddr;
26162625
struct arm_smmu_device *smmu;
26172626
struct device *dev = &pdev->dev;
26182627
bool bypass;
@@ -2630,6 +2639,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
26302639
dev_err(dev, "MMIO region too small (%pr)\n", res);
26312640
return -EINVAL;
26322641
}
2642+
ioaddr = res->start;
26332643

26342644
smmu->base = devm_ioremap_resource(dev, res);
26352645
if (IS_ERR(smmu->base))
@@ -2682,6 +2692,16 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
26822692
return ret;
26832693

26842694
/* And we're up. Go go go! */
2695+
ret = iommu_device_sysfs_add(&smmu->iommu, dev, NULL,
2696+
"smmu3.%pa", &ioaddr);
2697+
if (ret)
2698+
return ret;
2699+
2700+
iommu_device_set_ops(&smmu->iommu, &arm_smmu_ops);
2701+
iommu_device_set_fwnode(&smmu->iommu, dev->fwnode);
2702+
2703+
ret = iommu_device_register(&smmu->iommu);
2704+
26852705
iommu_register_instance(dev->fwnode, &arm_smmu_ops);
26862706

26872707
#ifdef CONFIG_PCI

drivers/iommu/arm-smmu.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,9 @@ struct arm_smmu_device {
380380
unsigned int *irqs;
381381

382382
u32 cavium_id_base; /* Specific to Cavium */
383+
384+
/* IOMMU core code handle */
385+
struct iommu_device iommu;
383386
};
384387

385388
enum arm_smmu_context_fmt {
@@ -1444,6 +1447,8 @@ static int arm_smmu_add_device(struct device *dev)
14441447
if (ret)
14451448
goto out_free;
14461449

1450+
iommu_device_link(&smmu->iommu, dev);
1451+
14471452
return 0;
14481453

14491454
out_free:
@@ -1456,10 +1461,17 @@ static int arm_smmu_add_device(struct device *dev)
14561461
static void arm_smmu_remove_device(struct device *dev)
14571462
{
14581463
struct iommu_fwspec *fwspec = dev->iommu_fwspec;
1464+
struct arm_smmu_master_cfg *cfg;
1465+
struct arm_smmu_device *smmu;
1466+
14591467

14601468
if (!fwspec || fwspec->ops != &arm_smmu_ops)
14611469
return;
14621470

1471+
cfg = fwspec->iommu_priv;
1472+
smmu = cfg->smmu;
1473+
1474+
iommu_device_unlink(&smmu->iommu, dev);
14631475
arm_smmu_master_free_smes(fwspec);
14641476
iommu_group_remove_device(dev);
14651477
kfree(fwspec->iommu_priv);
@@ -2011,6 +2023,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
20112023
static int arm_smmu_device_probe(struct platform_device *pdev)
20122024
{
20132025
struct resource *res;
2026+
resource_size_t ioaddr;
20142027
struct arm_smmu_device *smmu;
20152028
struct device *dev = &pdev->dev;
20162029
int num_irqs, i, err;
@@ -2031,6 +2044,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
20312044
return err;
20322045

20332046
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2047+
ioaddr = res->start;
20342048
smmu->base = devm_ioremap_resource(dev, res);
20352049
if (IS_ERR(smmu->base))
20362050
return PTR_ERR(smmu->base);
@@ -2091,6 +2105,22 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
20912105
}
20922106
}
20932107

2108+
err = iommu_device_sysfs_add(&smmu->iommu, smmu->dev, NULL,
2109+
"smmu.%pa", &ioaddr);
2110+
if (err) {
2111+
dev_err(dev, "Failed to register iommu in sysfs\n");
2112+
return err;
2113+
}
2114+
2115+
iommu_device_set_ops(&smmu->iommu, &arm_smmu_ops);
2116+
iommu_device_set_fwnode(&smmu->iommu, dev->fwnode);
2117+
2118+
err = iommu_device_register(&smmu->iommu);
2119+
if (err) {
2120+
dev_err(dev, "Failed to register iommu\n");
2121+
return err;
2122+
}
2123+
20942124
iommu_register_instance(dev->fwnode, &arm_smmu_ops);
20952125
platform_set_drvdata(pdev, smmu);
20962126
arm_smmu_device_reset(smmu);

0 commit comments

Comments
 (0)