]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
iommu/arm-smmu: Make use of the iommu_register interface
authorJoerg Roedel <jroedel@suse.de>
Wed, 1 Feb 2017 17:11:36 +0000 (18:11 +0100)
committerJoerg Roedel <jroedel@suse.de>
Fri, 10 Feb 2017 12:44:57 +0000 (13:44 +0100)
Also add the smmu devices to sysfs.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/arm-smmu-v3.c
drivers/iommu/arm-smmu.c

index 4d6ec444a9d63aa18232088bc9415c1f1eb6dfaa..32133e289ff67b7ea4ec38b92ad83c2c5f27109f 100644 (file)
@@ -616,6 +616,9 @@ struct arm_smmu_device {
        unsigned int                    sid_bits;
 
        struct arm_smmu_strtab_cfg      strtab_cfg;
+
+       /* IOMMU core code handle */
+       struct iommu_device             iommu;
 };
 
 /* SMMU private data for each master */
@@ -1795,8 +1798,10 @@ static int arm_smmu_add_device(struct device *dev)
        }
 
        group = iommu_group_get_for_dev(dev);
-       if (!IS_ERR(group))
+       if (!IS_ERR(group)) {
                iommu_group_put(group);
+               iommu_device_link(&smmu->iommu, dev);
+       }
 
        return PTR_ERR_OR_ZERO(group);
 }
@@ -1805,14 +1810,17 @@ static void arm_smmu_remove_device(struct device *dev)
 {
        struct iommu_fwspec *fwspec = dev->iommu_fwspec;
        struct arm_smmu_master_data *master;
+       struct arm_smmu_device *smmu;
 
        if (!fwspec || fwspec->ops != &arm_smmu_ops)
                return;
 
        master = fwspec->iommu_priv;
+       smmu = master->smmu;
        if (master && master->ste.valid)
                arm_smmu_detach_dev(dev);
        iommu_group_remove_device(dev);
+       iommu_device_unlink(&smmu->iommu, dev);
        kfree(master);
        iommu_fwspec_free(dev);
 }
@@ -2613,6 +2621,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 {
        int irq, ret;
        struct resource *res;
+       resource_size_t ioaddr;
        struct arm_smmu_device *smmu;
        struct device *dev = &pdev->dev;
        bool bypass;
@@ -2630,6 +2639,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
                dev_err(dev, "MMIO region too small (%pr)\n", res);
                return -EINVAL;
        }
+       ioaddr = res->start;
 
        smmu->base = devm_ioremap_resource(dev, res);
        if (IS_ERR(smmu->base))
@@ -2682,6 +2692,16 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
                return ret;
 
        /* And we're up. Go go go! */
+       ret = iommu_device_sysfs_add(&smmu->iommu, dev, NULL,
+                                    "smmu3.%pa", &ioaddr);
+       if (ret)
+               return ret;
+
+       iommu_device_set_ops(&smmu->iommu, &arm_smmu_ops);
+       iommu_device_set_fwnode(&smmu->iommu, dev->fwnode);
+
+       ret = iommu_device_register(&smmu->iommu);
+
        iommu_register_instance(dev->fwnode, &arm_smmu_ops);
 
 #ifdef CONFIG_PCI
index a60cded8a6eddf445dcb1e2b0177999c207c8a74..f4ce1e77344eda5fb7939add9b43ef1f61223f7f 100644 (file)
@@ -380,6 +380,9 @@ struct arm_smmu_device {
        unsigned int                    *irqs;
 
        u32                             cavium_id_base; /* Specific to Cavium */
+
+       /* IOMMU core code handle */
+       struct iommu_device             iommu;
 };
 
 enum arm_smmu_context_fmt {
@@ -1444,6 +1447,8 @@ static int arm_smmu_add_device(struct device *dev)
        if (ret)
                goto out_free;
 
+       iommu_device_link(&smmu->iommu, dev);
+
        return 0;
 
 out_free:
@@ -1456,10 +1461,17 @@ static int arm_smmu_add_device(struct device *dev)
 static void arm_smmu_remove_device(struct device *dev)
 {
        struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+       struct arm_smmu_master_cfg *cfg;
+       struct arm_smmu_device *smmu;
+
 
        if (!fwspec || fwspec->ops != &arm_smmu_ops)
                return;
 
+       cfg  = fwspec->iommu_priv;
+       smmu = cfg->smmu;
+
+       iommu_device_unlink(&smmu->iommu, dev);
        arm_smmu_master_free_smes(fwspec);
        iommu_group_remove_device(dev);
        kfree(fwspec->iommu_priv);
@@ -2011,6 +2023,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
        struct resource *res;
+       resource_size_t ioaddr;
        struct arm_smmu_device *smmu;
        struct device *dev = &pdev->dev;
        int num_irqs, i, err;
@@ -2031,6 +2044,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
                return err;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       ioaddr = res->start;
        smmu->base = devm_ioremap_resource(dev, res);
        if (IS_ERR(smmu->base))
                return PTR_ERR(smmu->base);
@@ -2091,6 +2105,22 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
                }
        }
 
+       err = iommu_device_sysfs_add(&smmu->iommu, smmu->dev, NULL,
+                                    "smmu.%pa", &ioaddr);
+       if (err) {
+               dev_err(dev, "Failed to register iommu in sysfs\n");
+               return err;
+       }
+
+       iommu_device_set_ops(&smmu->iommu, &arm_smmu_ops);
+       iommu_device_set_fwnode(&smmu->iommu, dev->fwnode);
+
+       err = iommu_device_register(&smmu->iommu);
+       if (err) {
+               dev_err(dev, "Failed to register iommu\n");
+               return err;
+       }
+
        iommu_register_instance(dev->fwnode, &arm_smmu_ops);
        platform_set_drvdata(pdev, smmu);
        arm_smmu_device_reset(smmu);