aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iommu/iommu.c')
-rw-r--r--drivers/iommu/iommu.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9a2f1960873b..dbe7f653bb7c 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -552,6 +552,19 @@ struct iommu_group *iommu_group_get(struct device *dev)
EXPORT_SYMBOL_GPL(iommu_group_get);
/**
+ * iommu_group_ref_get - Increment reference on a group
+ * @group: the group to use, must not be NULL
+ *
+ * This function is called by iommu drivers to take additional references on an
+ * existing group. Returns the given group for convenience.
+ */
+struct iommu_group *iommu_group_ref_get(struct iommu_group *group)
+{
+ kobject_get(group->devices_kobj);
+ return group;
+}
+
+/**
* iommu_group_put - Decrement group reference
* @group: the group to use
*
@@ -1615,6 +1628,46 @@ out:
return ret;
}
+struct iommu_instance {
+ struct list_head list;
+ struct fwnode_handle *fwnode;
+ const struct iommu_ops *ops;
+};
+static LIST_HEAD(iommu_instance_list);
+static DEFINE_SPINLOCK(iommu_instance_lock);
+
+void iommu_register_instance(struct fwnode_handle *fwnode,
+ const struct iommu_ops *ops)
+{
+ struct iommu_instance *iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
+
+ if (WARN_ON(!iommu))
+ return;
+
+ of_node_get(to_of_node(fwnode));
+ INIT_LIST_HEAD(&iommu->list);
+ iommu->fwnode = fwnode;
+ iommu->ops = ops;
+ spin_lock(&iommu_instance_lock);
+ list_add_tail(&iommu->list, &iommu_instance_list);
+ spin_unlock(&iommu_instance_lock);
+}
+
+const struct iommu_ops *iommu_get_instance(struct fwnode_handle *fwnode)
+{
+ struct iommu_instance *instance;
+ const struct iommu_ops *ops = NULL;
+
+ spin_lock(&iommu_instance_lock);
+ list_for_each_entry(instance, &iommu_instance_list, list)
+ if (instance->fwnode == fwnode) {
+ ops = instance->ops;
+ break;
+ }
+ spin_unlock(&iommu_instance_lock);
+ return ops;
+}
+
int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
const struct iommu_ops *ops)
{