Patchwork [PATCHv7,02/12] iommu/of: introduce a global iommu device list

login
register
mail settings
Submitter Hiroshi Doyu
Date Dec. 12, 2013, 7:57 a.m.
Message ID <1386835033-4701-3-git-send-email-hdoyu@nvidia.com>
Download mbox | patch
Permalink /patch/300561/
State Superseded, archived
Headers show

Comments

Hiroshi Doyu - Dec. 12, 2013, 7:57 a.m.
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>
---
v6:
New for v6.

Signed-off-by: Hiroshi Doyu <hdoyu@nvidia.com>
---
 drivers/iommu/of_iommu.c | 37 +++++++++++++++++++++++++++++++++++++
 include/linux/of_iommu.h | 16 ++++++++++++++++
 2 files changed, 53 insertions(+)
Stephen Warren - Dec. 16, 2013, 6:32 p.m.
On 12/12/2013 12:57 AM, Hiroshi Doyu wrote:
> 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.

> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c

> +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);

Now that the list is unlocked, the IOMMU could be removed from the list,
and the driver unregistered. Should you do something like
iommu_get(iommu); before the mutex_unlock() call, and call iommu_put()
somewhere (i.e. in the next patch ...)?
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index ee249bc..5d1aeb9 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -20,6 +20,43 @@ 
 #include <linux/export.h>
 #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 51a560f..a0aa9d4 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);
 
+extern void iommu_add(struct iommu *iommu);
+extern 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 */