Merge tag 'iommu-updates-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/joro...
[sfrench/cifs-2.6.git] / arch / powerpc / kernel / iommu.c
index 3e28579f7c625b802194f0cd7e8613339aa73aa5..ebe259bdd46298e0654fb681b0cf8853c8381079 100644 (file)
@@ -1280,13 +1280,19 @@ struct iommu_table_group_ops spapr_tce_table_group_ops = {
 /*
  * A simple iommu_ops to allow less cruft in generic VFIO code.
  */
-static int spapr_tce_blocking_iommu_attach_dev(struct iommu_domain *dom,
-                                              struct device *dev)
+static int
+spapr_tce_platform_iommu_attach_dev(struct iommu_domain *platform_domain,
+                                   struct device *dev)
 {
+       struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
        struct iommu_group *grp = iommu_group_get(dev);
        struct iommu_table_group *table_group;
        int ret = -EINVAL;
 
+       /* At first attach the ownership is already set */
+       if (!domain)
+               return 0;
+
        if (!grp)
                return -ENODEV;
 
@@ -1297,17 +1303,22 @@ static int spapr_tce_blocking_iommu_attach_dev(struct iommu_domain *dom,
        return ret;
 }
 
-static void spapr_tce_blocking_iommu_set_platform_dma(struct device *dev)
-{
-       struct iommu_group *grp = iommu_group_get(dev);
-       struct iommu_table_group *table_group;
+static const struct iommu_domain_ops spapr_tce_platform_domain_ops = {
+       .attach_dev = spapr_tce_platform_iommu_attach_dev,
+};
 
-       table_group = iommu_group_get_iommudata(grp);
-       table_group->ops->release_ownership(table_group);
-}
+static struct iommu_domain spapr_tce_platform_domain = {
+       .type = IOMMU_DOMAIN_PLATFORM,
+       .ops = &spapr_tce_platform_domain_ops,
+};
 
-static const struct iommu_domain_ops spapr_tce_blocking_domain_ops = {
-       .attach_dev = spapr_tce_blocking_iommu_attach_dev,
+static struct iommu_domain spapr_tce_blocked_domain = {
+       .type = IOMMU_DOMAIN_BLOCKED,
+       /*
+        * FIXME: SPAPR mixes blocked and platform behaviors, the blocked domain
+        * also sets the dma_api ops
+        */
+       .ops = &spapr_tce_platform_domain_ops,
 };
 
 static bool spapr_tce_iommu_capable(struct device *dev, enum iommu_cap cap)
@@ -1322,22 +1333,6 @@ static bool spapr_tce_iommu_capable(struct device *dev, enum iommu_cap cap)
        return false;
 }
 
-static struct iommu_domain *spapr_tce_iommu_domain_alloc(unsigned int type)
-{
-       struct iommu_domain *dom;
-
-       if (type != IOMMU_DOMAIN_BLOCKED)
-               return NULL;
-
-       dom = kzalloc(sizeof(*dom), GFP_KERNEL);
-       if (!dom)
-               return NULL;
-
-       dom->ops = &spapr_tce_blocking_domain_ops;
-
-       return dom;
-}
-
 static struct iommu_device *spapr_tce_iommu_probe_device(struct device *dev)
 {
        struct pci_dev *pdev;
@@ -1371,12 +1366,12 @@ static struct iommu_group *spapr_tce_iommu_device_group(struct device *dev)
 }
 
 static const struct iommu_ops spapr_tce_iommu_ops = {
+       .default_domain = &spapr_tce_platform_domain,
+       .blocked_domain = &spapr_tce_blocked_domain,
        .capable = spapr_tce_iommu_capable,
-       .domain_alloc = spapr_tce_iommu_domain_alloc,
        .probe_device = spapr_tce_iommu_probe_device,
        .release_device = spapr_tce_iommu_release_device,
        .device_group = spapr_tce_iommu_device_group,
-       .set_platform_dma_ops = spapr_tce_blocking_iommu_set_platform_dma,
 };
 
 static struct attribute *spapr_tce_iommu_attrs[] = {