summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroshi Doyu <hdoyu@nvidia.com>2014-05-30 14:20:15 +0300
committerThierry Reding <treding@nvidia.com>2014-06-03 17:19:52 +0200
commit9cc19bf84f0c018bbb5b509b739118c09d2ea600 (patch)
tree5c09334bd90c7db7155cda965372429e9b48f727
parent3060c2fe52dd8de1dead659235194529f8ed80e4 (diff)
iommu/of: introduce a global iommu device list
This enables to find an populated IOMMU device via a device node. This can be used to see if an dependee IOMMU is populated or not to keep correct device population order. Client devices need to wait an IOMMU to be populated. Suggested by Thierry Reding and copied his example code. Signed-off-by: Hiroshi Doyu <hdoyu@nvidia.com> Cc: Joerg Roedel <joro@8bytes.org> Cc: Thierry Reding <thierry.reding@gmail.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/iommu/of_iommu.c36
-rw-r--r--include/linux/of_iommu.h16
2 files changed, 52 insertions, 0 deletions
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index e550ccb7634..5d1aeb90eae 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -21,6 +21,42 @@
#include <linux/limits.h>
#include <linux/of.h>
#include <linux/of_iommu.h>
+#include <linux/device.h>
+
+static DEFINE_MUTEX(iommus_lock);
+static LIST_HEAD(iommus_list);
+
+void iommu_add(struct iommu *iommu)
+{
+ INIT_LIST_HEAD(&iommu->list);
+ mutex_lock(&iommus_lock);
+ list_add_tail(&iommu->list, &iommus_list);
+ mutex_unlock(&iommus_lock);
+}
+
+void iommu_del(struct iommu *iommu)
+{
+ INIT_LIST_HEAD(&iommu->list);
+ mutex_lock(&iommus_lock);
+ list_del(&iommu->list);
+ mutex_unlock(&iommus_lock);
+}
+
+static struct iommu *of_find_iommu_by_node(struct device_node *np)
+{
+ struct iommu *iommu;
+
+ mutex_lock(&iommus_lock);
+ list_for_each_entry(iommu, &iommus_list, list) {
+ if (iommu->dev->of_node == np) {
+ mutex_unlock(&iommus_lock);
+ return iommu;
+ }
+ }
+ mutex_unlock(&iommus_lock);
+
+ return NULL;
+}
/**
* of_get_dma_window - Parse *dma-window property and returns 0 if found.
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index 51a560f34bc..108306898c3 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -3,10 +3,18 @@
#ifdef CONFIG_OF_IOMMU
+struct iommu {
+ struct list_head list;
+ struct device *dev;
+};
+
extern int of_get_dma_window(struct device_node *dn, const char *prefix,
int index, unsigned long *busno, dma_addr_t *addr,
size_t *size);
+void iommu_add(struct iommu *iommu);
+void iommu_del(struct iommu *iommu);
+
#else
static inline int of_get_dma_window(struct device_node *dn, const char *prefix,
@@ -16,6 +24,14 @@ static inline int of_get_dma_window(struct device_node *dn, const char *prefix,
return -EINVAL;
}
+static inline void iommu_add(struct iommu *iommu)
+{
+}
+
+static inline void iommu_del(struct iommu *iommu)
+{
+}
+
#endif /* CONFIG_OF_IOMMU */
#endif /* __OF_IOMMU_H */