linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: thierry.reding@gmail.com (Thierry Reding)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC 01/10] iommu: Add IOMMU device registry
Date: Thu, 26 Jun 2014 22:49:41 +0200	[thread overview]
Message-ID: <1403815790-8548-2-git-send-email-thierry.reding@gmail.com> (raw)
In-Reply-To: <1403815790-8548-1-git-send-email-thierry.reding@gmail.com>

From: Thierry Reding <treding@nvidia.com>

Add an IOMMU device registry for drivers to register with and implement
a method for users of the IOMMU API to attach to an IOMMU device. This
allows to support deferred probing and gives the IOMMU API a convenient
hook to perform early initialization of a device if necessary.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/iommu/iommu.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/iommu.h | 27 +++++++++++++++
 2 files changed, 120 insertions(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 806b55d056b7..5e9e82c73bbf 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -29,8 +29,12 @@
 #include <linux/idr.h>
 #include <linux/notifier.h>
 #include <linux/err.h>
+#include <linux/of.h>
 #include <trace/events/iommu.h>
 
+static DEFINE_MUTEX(iommus_lock);
+static LIST_HEAD(iommus);
+
 static struct kset *iommu_group_kset;
 static struct ida iommu_group_ida;
 static struct mutex iommu_group_mutex;
@@ -1004,3 +1008,92 @@ int iommu_domain_set_attr(struct iommu_domain *domain,
 	return ret;
 }
 EXPORT_SYMBOL_GPL(iommu_domain_set_attr);
+
+int iommu_add(struct iommu *iommu)
+{
+	mutex_lock(&iommus_lock);
+	list_add_tail(&iommu->list, &iommus);
+	mutex_unlock(&iommus_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(iommu_add);
+
+void iommu_remove(struct iommu *iommu)
+{
+	mutex_lock(&iommus_lock);
+	list_del_init(&iommu->list);
+	mutex_unlock(&iommus_lock);
+}
+EXPORT_SYMBOL_GPL(iommu_remove);
+
+static int of_iommu_attach(struct device *dev)
+{
+	struct of_phandle_iter iter;
+	struct iommu *iommu;
+
+	mutex_lock(&iommus_lock);
+
+	of_property_for_each_phandle_with_args(iter, dev->of_node, "iommus",
+					       "#iommu-cells", 0) {
+		bool found = false;
+		int err;
+
+		/* skip disabled IOMMUs */
+		if (!of_device_is_available(iter.out_args.np))
+			continue;
+
+		list_for_each_entry(iommu, &iommus, list) {
+			if (iommu->dev->of_node == iter.out_args.np) {
+				err = iommu->ops->attach(iommu, dev);
+				if (err < 0) {
+				}
+
+				found = true;
+			}
+		}
+
+		if (!found) {
+			mutex_unlock(&iommus_lock);
+			return -EPROBE_DEFER;
+		}
+	}
+
+	mutex_unlock(&iommus_lock);
+
+	return 0;
+}
+
+static int of_iommu_detach(struct device *dev)
+{
+	/* TODO: implement */
+	return -ENOSYS;
+}
+
+int iommu_attach(struct device *dev)
+{
+	int err = 0;
+
+	if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
+		err = of_iommu_attach(dev);
+		if (!err)
+			return 0;
+	}
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(iommu_attach);
+
+int iommu_detach(struct device *dev)
+{
+	int err = 0;
+
+	if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
+		err = of_iommu_detach(dev);
+		if (!err)
+			return 0;
+	}
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(iommu_detach);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 284a4683fdc1..ac2ceef194d4 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -43,6 +43,17 @@ struct notifier_block;
 typedef int (*iommu_fault_handler_t)(struct iommu_domain *,
 			struct device *, unsigned long, int, void *);
 
+struct iommu {
+	struct device *dev;
+
+	struct list_head list;
+
+	const struct iommu_ops *ops;
+};
+
+int iommu_add(struct iommu *iommu);
+void iommu_remove(struct iommu *iommu);
+
 struct iommu_domain_geometry {
 	dma_addr_t aperture_start; /* First address that can be mapped    */
 	dma_addr_t aperture_end;   /* Last address that can be mapped     */
@@ -130,6 +141,9 @@ struct iommu_ops {
 	/* Get the numer of window per domain */
 	u32 (*domain_get_windows)(struct iommu_domain *domain);
 
+	int (*attach)(struct iommu *iommu, struct device *dev);
+	int (*detach)(struct iommu *iommu, struct device *dev);
+
 	unsigned long pgsize_bitmap;
 };
 
@@ -192,6 +206,10 @@ extern int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr,
 				      phys_addr_t offset, u64 size,
 				      int prot);
 extern void iommu_domain_window_disable(struct iommu_domain *domain, u32 wnd_nr);
+
+int iommu_attach(struct device *dev);
+int iommu_detach(struct device *dev);
+
 /**
  * report_iommu_fault() - report about an IOMMU fault to the IOMMU framework
  * @domain: the iommu domain where the fault has happened
@@ -396,6 +414,15 @@ static inline int iommu_domain_set_attr(struct iommu_domain *domain,
 	return -EINVAL;
 }
 
+static inline int iommu_attach(struct device *dev)
+{
+	return 0;
+}
+
+static inline int iommu_detach(struct device *dev)
+{
+	return 0;
+}
 #endif /* CONFIG_IOMMU_API */
 
 #endif /* __LINUX_IOMMU_H */
-- 
2.0.0

  reply	other threads:[~2014-06-26 20:49 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-26 20:49 [RFC 00/10] Add NVIDIA Tegra124 IOMMU support Thierry Reding
2014-06-26 20:49 ` Thierry Reding [this message]
2014-06-27  6:58   ` [RFC 01/10] iommu: Add IOMMU device registry Thierry Reding
2014-07-03 10:37     ` Varun Sethi
2014-07-04 11:05   ` Joerg Roedel
2014-07-04 13:47     ` Thierry Reding
2014-07-04 13:49       ` Will Deacon
2014-07-06 18:17         ` Arnd Bergmann
2014-07-07 11:42           ` Thierry Reding
2014-06-26 20:49 ` [PATCH v3 02/10] devicetree: Add generic IOMMU device tree bindings Thierry Reding
2014-06-27 13:55   ` Will Deacon
2014-06-30 22:24   ` Stephen Warren
2014-07-04  6:42   ` Varun Sethi
2014-07-04  9:05     ` Arnd Bergmann
2014-06-26 20:49 ` [RFC 03/10] of: Add NVIDIA Tegra124 memory controller binding Thierry Reding
2014-06-26 20:49 ` [RFC 04/10] memory: Add Tegra124 memory controller support Thierry Reding
2014-06-27  7:41   ` Joseph Lo
2014-06-27  8:17     ` Thierry Reding
2014-06-27  8:24       ` Hiroshi Doyu
2014-06-27  9:46   ` Hiroshi DOyu
2014-06-27 11:08     ` Thierry Reding
2014-06-27 21:33       ` Stephen Warren
2014-06-27 11:07   ` Arnd Bergmann
2014-06-27 11:15     ` Thierry Reding
2014-06-27 21:37       ` Stephen Warren
2014-06-27 13:29   ` Mikko Perttunen
2014-06-30 22:43   ` Stephen Warren
2014-07-01 12:14   ` Hiroshi Doyu
2014-06-26 20:49 ` [RFC 05/10] ARM: tegra: Add memory controller on Tegra124 Thierry Reding
2014-06-26 20:49 ` [RFC 06/10] ARM: tegra: tegra124: Enable IOMMU for display controllers Thierry Reding
2014-06-26 20:49 ` [RFC 07/10] ARM: tegra: tegra124: Enable IOMMU for SDMMC controllers Thierry Reding
2014-06-26 20:49 ` [RFC 08/10] ARM: tegra: Select ARM_DMA_USE_IOMMU Thierry Reding
2014-06-26 20:49 ` [RFC 09/10] drm/tegra: Add IOMMU support Thierry Reding
2014-06-27  9:46   ` Hiroshi DOyu
2014-06-27 10:54     ` Arnd Bergmann
2014-06-27 11:03       ` Hiroshi Doyu
2014-06-27 10:58     ` Thierry Reding
2014-09-30 18:48   ` Sean Paul
2014-10-01 15:54     ` Sean Paul
2014-10-02  8:39       ` Thierry Reding
2014-11-05  9:50       ` Thierry Reding
2014-11-05 10:26     ` Thierry Reding
2014-06-26 20:49 ` [RFC 10/10] mmc: sdhci-tegra: " Thierry Reding
2014-06-27  9:46   ` Hiroshi DOyu
2014-06-27 11:01     ` Thierry Reding

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1403815790-8548-2-git-send-email-thierry.reding@gmail.com \
    --to=thierry.reding@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).