summaryrefslogtreecommitdiffstats
path: root/include/linux/iommu.h
diff options
context:
space:
mode:
authorRobin Murphy <robin.murphy@arm.com>2016-09-13 10:54:14 +0100
committerWill Deacon <will.deacon@arm.com>2016-09-16 09:34:15 +0100
commit57f98d2f61e191ef9d06863c9ce3f8621f3671ef (patch)
treefd6d52282bcada86b0893b9972eaa5b8a5f219e1 /include/linux/iommu.h
parentb996444cf35e736621855e73f9d0762bd49f41f2 (diff)
downloadlinux-57f98d2f61e191ef9d06863c9ce3f8621f3671ef.tar.gz
linux-57f98d2f61e191ef9d06863c9ce3f8621f3671ef.tar.bz2
linux-57f98d2f61e191ef9d06863c9ce3f8621f3671ef.zip
iommu: Introduce iommu_fwspec
Introduce a common structure to hold the per-device firmware data that most IOMMU drivers need to keep track of. This enables us to configure much of that data from common firmware code, and consolidate a lot of the equivalent implementations, device look-up tables, etc. which are currently strewn across IOMMU drivers. This will also be enable us to address the outstanding "multiple IOMMUs on the platform bus" problem by tweaking IOMMU API calls to prefer dev->fwspec->ops before falling back to dev->bus->iommu_ops, and thus gracefully handle those troublesome systems which we currently cannot. As the first user, hook up the OF IOMMU configuration mechanism. The driver-defined nature of DT cells means that we still need the drivers to translate and add the IDs themselves, but future users such as the much less free-form ACPI IORT will be much simpler and self-contained. CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Suggested-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'include/linux/iommu.h')
-rw-r--r--include/linux/iommu.h39
1 files changed, 39 insertions, 0 deletions
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index a35fb8b42e1a..436dc21318af 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -331,10 +331,32 @@ extern struct iommu_group *pci_device_group(struct device *dev);
/* Generic device grouping function */
extern struct iommu_group *generic_device_group(struct device *dev);
+/**
+ * struct iommu_fwspec - per-device IOMMU instance data
+ * @ops: ops for this device's IOMMU
+ * @iommu_fwnode: firmware handle for this device's IOMMU
+ * @iommu_priv: IOMMU driver private data for this device
+ * @num_ids: number of associated device IDs
+ * @ids: IDs which this device may present to the IOMMU
+ */
+struct iommu_fwspec {
+ const struct iommu_ops *ops;
+ struct fwnode_handle *iommu_fwnode;
+ void *iommu_priv;
+ unsigned int num_ids;
+ u32 ids[1];
+};
+
+int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
+ const struct iommu_ops *ops);
+void iommu_fwspec_free(struct device *dev);
+int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
+
#else /* CONFIG_IOMMU_API */
struct iommu_ops {};
struct iommu_group {};
+struct iommu_fwspec {};
static inline bool iommu_present(struct bus_type *bus)
{
@@ -541,6 +563,23 @@ static inline void iommu_device_unlink(struct device *dev, struct device *link)
{
}
+static inline int iommu_fwspec_init(struct device *dev,
+ struct fwnode_handle *iommu_fwnode,
+ const struct iommu_ops *ops)
+{
+ return -ENODEV;
+}
+
+static inline void iommu_fwspec_free(struct device *dev)
+{
+}
+
+static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
+ int num_ids)
+{
+ return -ENODEV;
+}
+
#endif /* CONFIG_IOMMU_API */
#endif /* __LINUX_IOMMU_H */