Implement bus specific support for the fsl-mc bus including
registering the arm_smmu_ops and bus specific smmu device init.

Signed-off-by: Nipun Gupta <[email protected]>
Signed-off-by: Bharat Bhushan <[email protected]>
---
 drivers/iommu/arm-smmu.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index ab365ec..28d5dc8 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -47,6 +47,9 @@
 
 #include <linux/amba/bus.h>
 
+/* Include path will be changed once FSL-MC support is out from staging */
+#include <../drivers/staging/fsl-mc/include/fsl_mc_smmu.h>
+
 #include "io-pgtable.h"
 
 /* Maximum number of stream IDs assigned to a single device */
@@ -447,6 +450,11 @@ static struct device_node *dev_get_dev_node(struct device 
*dev)
                return bus->bridge->parent->of_node;
        }
 
+       if (dev_is_fsl_mc(dev)) {
+               while (dev_is_fsl_mc(dev))
+                       dev = dev->parent;
+       }
+
        return dev->of_node;
 }
 
@@ -1443,6 +1451,32 @@ static int arm_smmu_init_platform_device(struct device 
*dev,
        return 0;
 }
 
+static void __arm_smmu_release_fslmc_iommudata(void *data)
+{
+       kfree(data);
+}
+
+static int arm_smmu_init_fslmc_device(struct device *dev,
+                                     struct iommu_group *group)
+{
+       struct arm_smmu_master_cfg *cfg;
+
+       cfg = iommu_group_get_iommudata(group);
+       if (!cfg) {
+               cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+               if (!cfg)
+                       return -ENOMEM;
+
+               cfg->streamids[0] = fslmc_dev_streamid(dev);
+               cfg->num_streamids = 1;
+
+               iommu_group_set_iommudata(group, cfg,
+                                         __arm_smmu_release_fslmc_iommudata);
+       }
+
+       return 0;
+}
+
 static int arm_smmu_add_device(struct device *dev)
 {
        struct iommu_group *group;
@@ -1467,6 +1501,8 @@ static struct iommu_group *arm_smmu_device_group(struct 
device *dev)
 
        if (dev_is_pci(dev))
                group = pci_device_group(dev);
+       else if (dev_is_fsl_mc(dev))
+               group = fslmc_device_group(dev);
        else
                group = generic_device_group(dev);
 
@@ -1475,6 +1511,8 @@ static struct iommu_group *arm_smmu_device_group(struct 
device *dev)
 
        if (dev_is_pci(dev))
                ret = arm_smmu_init_pci_device(to_pci_dev(dev), group);
+       else if (dev_is_fsl_mc(dev))
+               ret = arm_smmu_init_fslmc_device(dev, group);
        else
                ret = arm_smmu_init_platform_device(dev, group);
 
@@ -2102,6 +2140,11 @@ static int __init arm_smmu_init(void)
        }
 #endif
 
+#ifdef CONFIG_FSL_MC_BUS
+       if (!iommu_present(&fsl_mc_bus_type))
+               bus_set_iommu(&fsl_mc_bus_type, &arm_smmu_ops);
+#endif
+
        return 0;
 }
 
-- 
1.9.1

_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to