Merge tag 'dma-mapping-5.20-2022-08-06' of git://git.infradead.org/users/hch/dma...
[platform/kernel/linux-starfive.git] / drivers / iommu / iommu.c
index 2844a3e..780fb70 100644 (file)
@@ -259,7 +259,8 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
        return 0;
 
 out_release:
-       ops->release_device(dev);
+       if (ops->release_device)
+               ops->release_device(dev);
 
 out_module_put:
        module_put(ops->owner);
@@ -272,7 +273,7 @@ err_free:
 
 int iommu_probe_device(struct device *dev)
 {
-       const struct iommu_ops *ops = dev->bus->iommu_ops;
+       const struct iommu_ops *ops;
        struct iommu_group *group;
        int ret;
 
@@ -313,6 +314,7 @@ int iommu_probe_device(struct device *dev)
        mutex_unlock(&group->mutex);
        iommu_group_put(group);
 
+       ops = dev_iommu_ops(dev);
        if (ops->probe_finalize)
                ops->probe_finalize(dev);
 
@@ -336,7 +338,8 @@ void iommu_release_device(struct device *dev)
        iommu_device_unlink(dev->iommu->iommu_dev, dev);
 
        ops = dev_iommu_ops(dev);
-       ops->release_device(dev);
+       if (ops->release_device)
+               ops->release_device(dev);
 
        iommu_group_remove_device(dev);
        module_put(ops->owner);
@@ -600,7 +603,7 @@ static void iommu_group_release(struct kobject *kobj)
        if (group->iommu_data_release)
                group->iommu_data_release(group->iommu_data);
 
-       ida_simple_remove(&iommu_group_ida, group->id);
+       ida_free(&iommu_group_ida, group->id);
 
        if (group->default_domain)
                iommu_domain_free(group->default_domain);
@@ -641,7 +644,7 @@ struct iommu_group *iommu_group_alloc(void)
        INIT_LIST_HEAD(&group->devices);
        INIT_LIST_HEAD(&group->entry);
 
-       ret = ida_simple_get(&iommu_group_ida, 0, 0, GFP_KERNEL);
+       ret = ida_alloc(&iommu_group_ida, GFP_KERNEL);
        if (ret < 0) {
                kfree(group);
                return ERR_PTR(ret);
@@ -651,7 +654,7 @@ struct iommu_group *iommu_group_alloc(void)
        ret = kobject_init_and_add(&group->kobj, &iommu_group_ktype,
                                   NULL, "%d", group->id);
        if (ret) {
-               ida_simple_remove(&iommu_group_ida, group->id);
+               ida_free(&iommu_group_ida, group->id);
                kobject_put(&group->kobj);
                return ERR_PTR(ret);
        }
@@ -2580,32 +2583,25 @@ void iommu_get_resv_regions(struct device *dev, struct list_head *list)
                ops->get_resv_regions(dev, list);
 }
 
-void iommu_put_resv_regions(struct device *dev, struct list_head *list)
-{
-       const struct iommu_ops *ops = dev_iommu_ops(dev);
-
-       if (ops->put_resv_regions)
-               ops->put_resv_regions(dev, list);
-}
-
 /**
- * generic_iommu_put_resv_regions - Reserved region driver helper
+ * iommu_put_resv_regions - release resered regions
  * @dev: device for which to free reserved regions
  * @list: reserved region list for device
  *
- * IOMMU drivers can use this to implement their .put_resv_regions() callback
- * for simple reservations. Memory allocated for each reserved region will be
- * freed. If an IOMMU driver allocates additional resources per region, it is
- * going to have to implement a custom callback.
+ * This releases a reserved region list acquired by iommu_get_resv_regions().
  */
-void generic_iommu_put_resv_regions(struct device *dev, struct list_head *list)
+void iommu_put_resv_regions(struct device *dev, struct list_head *list)
 {
        struct iommu_resv_region *entry, *next;
 
-       list_for_each_entry_safe(entry, next, list, list)
-               kfree(entry);
+       list_for_each_entry_safe(entry, next, list, list) {
+               if (entry->free)
+                       entry->free(dev, entry);
+               else
+                       kfree(entry);
+       }
 }
-EXPORT_SYMBOL(generic_iommu_put_resv_regions);
+EXPORT_SYMBOL(iommu_put_resv_regions);
 
 struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
                                                  size_t length, int prot,
@@ -2755,19 +2751,6 @@ int iommu_dev_disable_feature(struct device *dev, enum iommu_dev_features feat)
 }
 EXPORT_SYMBOL_GPL(iommu_dev_disable_feature);
 
-bool iommu_dev_feature_enabled(struct device *dev, enum iommu_dev_features feat)
-{
-       if (dev->iommu && dev->iommu->iommu_dev) {
-               const struct iommu_ops *ops = dev->iommu->iommu_dev->ops;
-
-               if (ops->dev_feat_enabled)
-                       return ops->dev_feat_enabled(dev, feat);
-       }
-
-       return false;
-}
-EXPORT_SYMBOL_GPL(iommu_dev_feature_enabled);
-
 /**
  * iommu_sva_bind_device() - Bind a process address space to a device
  * @dev: the device