iommu/msm: Make use of iommu_device_register interface
authorJoerg Roedel <jroedel@suse.de>
Thu, 2 Feb 2017 17:52:34 +0000 (18:52 +0100)
committerJoerg Roedel <jroedel@suse.de>
Fri, 10 Feb 2017 12:44:57 +0000 (13:44 +0100)
Register the MSM IOMMUs to the iommu core and add sysfs
entries for that driver.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/msm_iommu.c
drivers/iommu/msm_iommu.h

index b09692bb5b0a209c321401253a853c652ed374e2..30795cbab5efe2ed756fb68a3b94e6886dc6ae59 100644 (file)
@@ -371,6 +371,58 @@ static int msm_iommu_domain_config(struct msm_priv *priv)
        return 0;
 }
 
+/* Must be called under msm_iommu_lock */
+static struct msm_iommu_dev *find_iommu_for_dev(struct device *dev)
+{
+       struct msm_iommu_dev *iommu, *ret = NULL;
+       struct msm_iommu_ctx_dev *master;
+
+       list_for_each_entry(iommu, &qcom_iommu_devices, dev_node) {
+               master = list_first_entry(&iommu->ctx_list,
+                                         struct msm_iommu_ctx_dev,
+                                         list);
+               if (master->of_node == dev->of_node) {
+                       ret = iommu;
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+static int msm_iommu_add_device(struct device *dev)
+{
+       struct msm_iommu_dev *iommu;
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&msm_iommu_lock, flags);
+
+       iommu = find_iommu_for_dev(dev);
+       if (iommu)
+               iommu_device_link(&iommu->iommu, dev);
+       else
+               ret = -ENODEV;
+
+       spin_unlock_irqrestore(&msm_iommu_lock, flags);
+
+       return ret;
+}
+
+static void msm_iommu_remove_device(struct device *dev)
+{
+       struct msm_iommu_dev *iommu;
+       unsigned long flags;
+
+       spin_lock_irqsave(&msm_iommu_lock, flags);
+
+       iommu = find_iommu_for_dev(dev);
+       if (iommu)
+               iommu_device_unlink(&iommu->iommu, dev);
+
+       spin_unlock_irqrestore(&msm_iommu_lock, flags);
+}
+
 static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 {
        int ret = 0;
@@ -646,6 +698,8 @@ static struct iommu_ops msm_iommu_ops = {
        .unmap = msm_iommu_unmap,
        .map_sg = default_iommu_map_sg,
        .iova_to_phys = msm_iommu_iova_to_phys,
+       .add_device = msm_iommu_add_device,
+       .remove_device = msm_iommu_remove_device,
        .pgsize_bitmap = MSM_IOMMU_PGSIZES,
        .of_xlate = qcom_iommu_of_xlate,
 };
@@ -653,6 +707,7 @@ static struct iommu_ops msm_iommu_ops = {
 static int msm_iommu_probe(struct platform_device *pdev)
 {
        struct resource *r;
+       resource_size_t ioaddr;
        struct msm_iommu_dev *iommu;
        int ret, par, val;
 
@@ -696,6 +751,7 @@ static int msm_iommu_probe(struct platform_device *pdev)
                ret = PTR_ERR(iommu->base);
                goto fail;
        }
+       ioaddr = r->start;
 
        iommu->irq = platform_get_irq(pdev, 0);
        if (iommu->irq < 0) {
@@ -737,6 +793,23 @@ static int msm_iommu_probe(struct platform_device *pdev)
        }
 
        list_add(&iommu->dev_node, &qcom_iommu_devices);
+
+       ret = iommu_device_sysfs_add(&iommu->iommu, iommu->dev, NULL,
+                                    "msm-smmu.%pa", &ioaddr);
+       if (ret) {
+               pr_err("Could not add msm-smmu at %pa to sysfs\n", &ioaddr);
+               goto fail;
+       }
+
+       iommu_device_set_ops(&iommu->iommu, &msm_iommu_ops);
+       iommu_device_set_fwnode(&iommu->iommu, &pdev->dev.of_node->fwnode);
+
+       ret = iommu_device_register(&iommu->iommu);
+       if (ret) {
+               pr_err("Could not register msm-smmu at %pa\n", &ioaddr);
+               goto fail;
+       }
+
        of_iommu_set_ops(pdev->dev.of_node, &msm_iommu_ops);
 
        pr_info("device mapped at %p, irq %d with %d ctx banks\n",
index 4ca25d50d679687d81aaac8b0913e3e1a18f6768..ae92d2779c420ad46aaee5afe3a13c3041f78b51 100644 (file)
@@ -19,6 +19,7 @@
 #define MSM_IOMMU_H
 
 #include <linux/interrupt.h>
+#include <linux/iommu.h>
 #include <linux/clk.h>
 
 /* Sharability attributes of MSM IOMMU mappings */
@@ -68,6 +69,8 @@ struct msm_iommu_dev {
        struct list_head dom_node;
        struct list_head ctx_list;
        DECLARE_BITMAP(context_map, IOMMU_MAX_CBS);
+
+       struct iommu_device iommu;
 };
 
 /**