All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Gunthorpe <jgg@nvidia.com>
To: acpica-devel@lists.linux.dev, Andy Gross <agross@kernel.org>,
	Alim Akhtar <alim.akhtar@samsung.com>,
	Alyssa Rosenzweig <alyssa@rosenzweig.io>,
	Bjorn Andersson <andersson@kernel.org>,
	AngeloGioacchino Del Regno
	<angelogioacchino.delregno@collabora.com>,
	asahi@lists.linux.dev,
	Baolin Wang <baolin.wang@linux.alibaba.com>,
	devicetree@vger.kernel.org, Frank Rowand <frowand.list@gmail.com>,
	Hanjun Guo <guohanjun@huawei.com>,
	"Gustavo A. R. Silva" <gustavoars@kernel.org>,
	Heiko Stuebner <heiko@sntech.de>,
	iommu@lists.linux.dev,
	Jean-Philippe Brucker <jean-philippe@linaro.org>,
	Jernej Skrabec <jernej.skrabec@gmail.com>,
	Jonathan Hunter <jonathanh@nvidia.com>,
	Joerg Roedel <joro@8bytes.org>, Kees Cook <keescook@chromium.org>,
	Konrad Dybcio <konrad.dybcio@linaro.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>,
	Len Brown <lenb@kernel.org>,
	linux-acpi@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-arm-msm@vger.kernel.org, linux-hardening@vger.kernel.org,
	linux-mediatek@lists.infradead.org,
	linux-rockchip@lists.infradead.org,
	linux-samsung-soc@vger.kernel.org, linux-sunxi@lists.linux.dev,
	linux-tegra@vger.kernel.org,
	Lorenzo Pieralisi <lpieralisi@kernel.org>,
	Marek Szyprowski <m.szyprowski@samsung.com>,
	Hector Martin <marcan@marcan.st>,
	Matthias Brugger <matthias.bgg@gmail.com>,
	Orson Zhai <orsonzhai@gmail.com>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	Rob Clark <robdclark@gmail.com>,
	Robert Moore <robert.moore@intel.com>,
	Rob Herring <robh+dt@kernel.org>,
	Robin Murphy <robin.murphy@arm.com>,
	Samuel Holland <samuel@sholland.org>,
	Sudeep Holla <sudeep.holla@arm.com>,
	Sven Peter <sven@svenpeter.dev>,
	Thierry Reding <thierry.reding@gmail.com>,
	Krishna Reddy <vdumpa@nvidia.com>,
	virtualization@lists.linux.dev, Chen-Yu Tsai <wens@csie.org>,
	Will Deacon <will@kernel.org>, Yong Wu <yong.wu@mediatek.com>,
	Chunyan Zhang <zhang.lyra@gmail.com>
Cc: "André Draszik" <andre.draszik@linaro.org>, patches@lists.linux.dev
Subject: [PATCH 18/30] iommu/tegra: Move to iommu_fw_alloc_per_device_ids()
Date: Wed, 29 Nov 2023 21:10:25 -0400	[thread overview]
Message-ID: <18-v1-f82a05539a64+5042-iommu_fwspec_p2_jgg@nvidia.com> (raw)
In-Reply-To: <0-v1-f82a05539a64+5042-iommu_fwspec_p2_jgg@nvidia.com>

Tegra supports a single iommu instance with multiple ids.

Introduce a per-device data to store the iommu and ids list. Allocate and
initialize it with iommu_fw_alloc_per_device_ids(). Remove
tegra_smmu_of_xlate().

This now checks that all the iommu instances are the same.

Tegra can self-probe without having to go through the fwspec path because
it self-initializes the fwspec. Use iommu_of_allow_bus_probe() to achieve
the same thing.

Convert the rest of the funcs from calling dev_iommu_fwspec_get() to using
the per-device data and remove all use of fwspec.

Convert the places using dev_iommu_priv_get() to use the per-device data
not the iommu.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/tegra-smmu.c | 154 +++++++++++--------------------------
 1 file changed, 47 insertions(+), 107 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index cf563db3e3b48d..1daa92f524452b 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -7,6 +7,7 @@
 #include <linux/debugfs.h>
 #include <linux/err.h>
 #include <linux/iommu.h>
+#include <linux/iommu-driver.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
@@ -19,6 +20,8 @@
 #include <soc/tegra/ahb.h>
 #include <soc/tegra/mc.h>
 
+static const struct iommu_ops tegra_smmu_ops;
+
 struct tegra_smmu_group {
 	struct list_head list;
 	struct tegra_smmu *smmu;
@@ -49,6 +52,12 @@ struct tegra_smmu {
 	struct iommu_device iommu;	/* IOMMU Core code handle */
 };
 
+struct tegra_smmu_device {
+	struct tegra_smmu *smmu;
+	unsigned int num_ids;
+	u32 ids[] __counted_by(num_ids);
+};
+
 struct tegra_smmu_as {
 	struct iommu_domain domain;
 	struct tegra_smmu *smmu;
@@ -477,21 +486,18 @@ static void tegra_smmu_as_unprepare(struct tegra_smmu *smmu,
 static int tegra_smmu_attach_dev(struct iommu_domain *domain,
 				 struct device *dev)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-	struct tegra_smmu *smmu = dev_iommu_priv_get(dev);
+	struct tegra_smmu_device *smmu_device = dev_iommu_priv_get(dev);
+	struct tegra_smmu *smmu = smmu_device->smmu;
 	struct tegra_smmu_as *as = to_smmu_as(domain);
 	unsigned int index;
 	int err;
 
-	if (!fwspec)
-		return -ENOENT;
-
-	for (index = 0; index < fwspec->num_ids; index++) {
+	for (index = 0; index < smmu_device->num_ids; index++) {
 		err = tegra_smmu_as_prepare(smmu, as);
 		if (err)
 			goto disable;
 
-		tegra_smmu_enable(smmu, fwspec->ids[index], as->id);
+		tegra_smmu_enable(smmu, smmu_device->ids[index], as->id);
 	}
 
 	if (index == 0)
@@ -501,7 +507,7 @@ static int tegra_smmu_attach_dev(struct iommu_domain *domain,
 
 disable:
 	while (index--) {
-		tegra_smmu_disable(smmu, fwspec->ids[index], as->id);
+		tegra_smmu_disable(smmu, smmu_device->ids[index], as->id);
 		tegra_smmu_as_unprepare(smmu, as);
 	}
 
@@ -511,22 +517,19 @@ static int tegra_smmu_attach_dev(struct iommu_domain *domain,
 static int tegra_smmu_identity_attach(struct iommu_domain *identity_domain,
 				      struct device *dev)
 {
+	struct tegra_smmu_device *smmu_device = dev_iommu_priv_get(dev);
 	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	struct tegra_smmu_as *as;
 	struct tegra_smmu *smmu;
 	unsigned int index;
 
-	if (!fwspec)
-		return -ENODEV;
-
 	if (domain == identity_domain || !domain)
 		return 0;
 
 	as = to_smmu_as(domain);
 	smmu = as->smmu;
-	for (index = 0; index < fwspec->num_ids; index++) {
-		tegra_smmu_disable(smmu, fwspec->ids[index], as->id);
+	for (index = 0; index < smmu_device->num_ids; index++) {
+		tegra_smmu_disable(smmu, smmu_device->ids[index], as->id);
 		tegra_smmu_as_unprepare(smmu, as);
 	}
 	return 0;
@@ -811,77 +814,34 @@ static phys_addr_t tegra_smmu_iova_to_phys(struct iommu_domain *domain,
 	return SMMU_PFN_PHYS(pfn) + SMMU_OFFSET_IN_PAGE(iova);
 }
 
-static struct tegra_smmu *tegra_smmu_find(struct device_node *np)
+static struct iommu_device *
+tegra_smmu_probe_device(struct iommu_probe_info *pinf)
 {
-	struct platform_device *pdev;
-	struct tegra_mc *mc;
+	struct tegra_smmu_device *smmu_device;
+	struct tegra_smmu *smmu;
 
-	pdev = of_find_device_by_node(np);
-	if (!pdev)
-		return NULL;
+	iommu_of_allow_bus_probe(pinf);
+	smmu = iommu_of_get_single_iommu(pinf, &tegra_smmu_ops, 1,
+					 struct tegra_smmu, iommu);
+	if (IS_ERR(smmu))
+		return ERR_CAST(smmu);
 
-	mc = platform_get_drvdata(pdev);
-	if (!mc) {
-		put_device(&pdev->dev);
-		return NULL;
-	}
-
-	return mc->smmu;
-}
-
-static int tegra_smmu_configure(struct tegra_smmu *smmu, struct device *dev,
-				struct of_phandle_args *args)
-{
-	const struct iommu_ops *ops = smmu->iommu.ops;
-	int err;
-
-	err = iommu_fwspec_init(dev, &dev->of_node->fwnode, ops);
-	if (err < 0) {
-		dev_err(dev, "failed to initialize fwspec: %d\n", err);
-		return err;
-	}
-
-	err = ops->of_xlate(dev, args);
-	if (err < 0) {
-		dev_err(dev, "failed to parse SW group ID: %d\n", err);
-		iommu_fwspec_free(dev);
-		return err;
-	}
-
-	return 0;
-}
-
-static struct iommu_device *tegra_smmu_probe_device(struct device *dev)
-{
-	struct device_node *np = dev->of_node;
-	struct tegra_smmu *smmu = NULL;
-	struct of_phandle_args args;
-	unsigned int index = 0;
-	int err;
-
-	while (of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index,
-					  &args) == 0) {
-		smmu = tegra_smmu_find(args.np);
-		if (smmu) {
-			err = tegra_smmu_configure(smmu, dev, &args);
-
-			if (err < 0) {
-				of_node_put(args.np);
-				return ERR_PTR(err);
-			}
-		}
-
-		of_node_put(args.np);
-		index++;
-	}
-
-	smmu = dev_iommu_priv_get(dev);
-	if (!smmu)
-		return ERR_PTR(-ENODEV);
+	smmu_device = iommu_fw_alloc_per_device_ids(pinf, smmu_device);
+	if (IS_ERR(smmu_device))
+		return ERR_CAST(smmu_device);
+	smmu_device->smmu = smmu;
 
+	dev_iommu_priv_set(pinf->dev, smmu_device);
 	return &smmu->iommu;
 }
 
+static void tegra_smmu_release_device(struct device *dev)
+{
+	struct tegra_smmu_device *smmu_device = dev_iommu_priv_get(dev);
+
+	kfree(smmu_device);
+}
+
 static const struct tegra_smmu_group_soc *
 tegra_smmu_find_group(struct tegra_smmu *smmu, unsigned int swgroup)
 {
@@ -907,10 +867,10 @@ static void tegra_smmu_group_release(void *iommu_data)
 
 static struct iommu_group *tegra_smmu_device_group(struct device *dev)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-	struct tegra_smmu *smmu = dev_iommu_priv_get(dev);
+	struct tegra_smmu_device *smmu_device = dev_iommu_priv_get(dev);
+	struct tegra_smmu *smmu = smmu_device->smmu;
 	const struct tegra_smmu_group_soc *soc;
-	unsigned int swgroup = fwspec->ids[0];
+	unsigned int swgroup = smmu_device->ids[0];
 	struct tegra_smmu_group *group;
 	struct iommu_group *grp;
 
@@ -958,27 +918,6 @@ static struct iommu_group *tegra_smmu_device_group(struct device *dev)
 	return group->group;
 }
 
-static int tegra_smmu_of_xlate(struct device *dev,
-			       struct of_phandle_args *args)
-{
-	struct platform_device *iommu_pdev = of_find_device_by_node(args->np);
-	struct tegra_mc *mc = platform_get_drvdata(iommu_pdev);
-	u32 id = args->args[0];
-
-	/*
-	 * Note: we are here releasing the reference of &iommu_pdev->dev, which
-	 * is mc->dev. Although some functions in tegra_smmu_ops may keep using
-	 * its private data beyond this point, it's still safe to do so because
-	 * the SMMU parent device is the same as the MC, so the reference count
-	 * isn't strictly necessary.
-	 */
-	put_device(&iommu_pdev->dev);
-
-	dev_iommu_priv_set(dev, mc->smmu);
-
-	return iommu_fwspec_add_ids(dev, &id, 1);
-}
-
 static int tegra_smmu_def_domain_type(struct device *dev)
 {
 	/*
@@ -991,11 +930,11 @@ static int tegra_smmu_def_domain_type(struct device *dev)
 
 static bool tegra_smmu_get_stream_id(struct device *dev, u32 *stream_id)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct tegra_smmu_device *smmu_device = dev_iommu_priv_get(dev);
 
-	if (fwspec->num_ids != 1)
+	if (smmu_device->num_ids != 1)
 		return false;
-	*stream_id = fwspec->ids[0] & 0xffff;
+	*stream_id = smmu_device->ids[0] & 0xffff;
 	return true;
 }
 
@@ -1003,9 +942,10 @@ static const struct iommu_ops tegra_smmu_ops = {
 	.identity_domain = &tegra_smmu_identity_domain,
 	.def_domain_type = &tegra_smmu_def_domain_type,
 	.domain_alloc_paging = tegra_smmu_domain_alloc_paging,
-	.probe_device = tegra_smmu_probe_device,
+	.probe_device_pinf = tegra_smmu_probe_device,
+	.release_device = tegra_smmu_release_device,
 	.device_group = tegra_smmu_device_group,
-	.of_xlate = tegra_smmu_of_xlate,
+	.of_xlate = iommu_dummy_of_xlate,
 	.tegra_dev_iommu_get_stream_id = tegra_smmu_get_stream_id,
 	.pgsize_bitmap = SZ_4K,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
-- 
2.42.0


WARNING: multiple messages have this Message-ID (diff)
From: Jason Gunthorpe <jgg@nvidia.com>
To: acpica-devel@lists.linux.dev, Andy Gross <agross@kernel.org>,
	Alim Akhtar <alim.akhtar@samsung.com>,
	Alyssa Rosenzweig <alyssa@rosenzweig.io>,
	Bjorn Andersson <andersson@kernel.org>,
	AngeloGioacchino Del Regno
	<angelogioacchino.delregno@collabora.com>,
	asahi@lists.linux.dev,
	Baolin Wang <baolin.wang@linux.alibaba.com>,
	devicetree@vger.kernel.org, Frank Rowand <frowand.list@gmail.com>,
	Hanjun Guo <guohanjun@huawei.com>,
	"Gustavo A. R. Silva" <gustavoars@kernel.org>,
	Heiko Stuebner <heiko@sntech.de>,
	iommu@lists.linux.dev,
	Jean-Philippe Brucker <jean-philippe@linaro.org>,
	Jernej Skrabec <jernej.skrabec@gmail.com>,
	Jonathan Hunter <jonathanh@nvidia.com>,
	Joerg Roedel <joro@8bytes.org>, Kees Cook <keescook@chromium.org>,
	Konrad Dybcio <konrad.dybcio@linaro.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>,
	Len Brown <lenb@kernel.org>,
	linux-acpi@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-arm-msm@vger.kernel.org, linux-hardening@vger.kernel.org,
	linux-mediatek@lists.infradead.org,
	linux-rockchip@lists.infradead.org,
	linux-samsung-soc@vger.kernel.org, linux-sunxi@lists.linux.dev,
	linux-tegra@vger.kernel.org,
	Lorenzo Pieralisi <lpieralisi@kernel.org>,
	Marek Szyprowski <m.szyprowski@samsung.com>,
	Hector Martin <marcan@marcan.st>,
	Matthias Brugger <matthias.bgg@gmail.com>,
	Orson Zhai <orsonzhai@gmail.com>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	Rob Clark <robdclark@gmail.com>,
	Robert Moore <robert.moore@intel.com>,
	Rob Herring <robh+dt@kernel.org>,
	Robin Murphy <robin.murphy@arm.com>,
	Samuel Holland <samuel@sholland.org>,
	Sudeep Holla <sudeep.holla@arm.com>,
	Sven Peter <sven@svenpeter.dev>,
	Thierry Reding <thierry.reding@gmail.com>,
	Krishna Reddy <vdumpa@nvidia.com>,
	virtualization@lists.linux.dev, Chen-Yu Tsai <wens@csie.org>,
	Will Deacon <will@kernel.org>, Yong Wu <yong.wu@mediatek.com>,
	Chunyan Zhang <zhang.lyra@gmail.com>
Cc: "André Draszik" <andre.draszik@linaro.org>, patches@lists.linux.dev
Subject: [PATCH 18/30] iommu/tegra: Move to iommu_fw_alloc_per_device_ids()
Date: Wed, 29 Nov 2023 21:10:25 -0400	[thread overview]
Message-ID: <18-v1-f82a05539a64+5042-iommu_fwspec_p2_jgg@nvidia.com> (raw)
In-Reply-To: <0-v1-f82a05539a64+5042-iommu_fwspec_p2_jgg@nvidia.com>

Tegra supports a single iommu instance with multiple ids.

Introduce a per-device data to store the iommu and ids list. Allocate and
initialize it with iommu_fw_alloc_per_device_ids(). Remove
tegra_smmu_of_xlate().

This now checks that all the iommu instances are the same.

Tegra can self-probe without having to go through the fwspec path because
it self-initializes the fwspec. Use iommu_of_allow_bus_probe() to achieve
the same thing.

Convert the rest of the funcs from calling dev_iommu_fwspec_get() to using
the per-device data and remove all use of fwspec.

Convert the places using dev_iommu_priv_get() to use the per-device data
not the iommu.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/tegra-smmu.c | 154 +++++++++++--------------------------
 1 file changed, 47 insertions(+), 107 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index cf563db3e3b48d..1daa92f524452b 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -7,6 +7,7 @@
 #include <linux/debugfs.h>
 #include <linux/err.h>
 #include <linux/iommu.h>
+#include <linux/iommu-driver.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
@@ -19,6 +20,8 @@
 #include <soc/tegra/ahb.h>
 #include <soc/tegra/mc.h>
 
+static const struct iommu_ops tegra_smmu_ops;
+
 struct tegra_smmu_group {
 	struct list_head list;
 	struct tegra_smmu *smmu;
@@ -49,6 +52,12 @@ struct tegra_smmu {
 	struct iommu_device iommu;	/* IOMMU Core code handle */
 };
 
+struct tegra_smmu_device {
+	struct tegra_smmu *smmu;
+	unsigned int num_ids;
+	u32 ids[] __counted_by(num_ids);
+};
+
 struct tegra_smmu_as {
 	struct iommu_domain domain;
 	struct tegra_smmu *smmu;
@@ -477,21 +486,18 @@ static void tegra_smmu_as_unprepare(struct tegra_smmu *smmu,
 static int tegra_smmu_attach_dev(struct iommu_domain *domain,
 				 struct device *dev)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-	struct tegra_smmu *smmu = dev_iommu_priv_get(dev);
+	struct tegra_smmu_device *smmu_device = dev_iommu_priv_get(dev);
+	struct tegra_smmu *smmu = smmu_device->smmu;
 	struct tegra_smmu_as *as = to_smmu_as(domain);
 	unsigned int index;
 	int err;
 
-	if (!fwspec)
-		return -ENOENT;
-
-	for (index = 0; index < fwspec->num_ids; index++) {
+	for (index = 0; index < smmu_device->num_ids; index++) {
 		err = tegra_smmu_as_prepare(smmu, as);
 		if (err)
 			goto disable;
 
-		tegra_smmu_enable(smmu, fwspec->ids[index], as->id);
+		tegra_smmu_enable(smmu, smmu_device->ids[index], as->id);
 	}
 
 	if (index == 0)
@@ -501,7 +507,7 @@ static int tegra_smmu_attach_dev(struct iommu_domain *domain,
 
 disable:
 	while (index--) {
-		tegra_smmu_disable(smmu, fwspec->ids[index], as->id);
+		tegra_smmu_disable(smmu, smmu_device->ids[index], as->id);
 		tegra_smmu_as_unprepare(smmu, as);
 	}
 
@@ -511,22 +517,19 @@ static int tegra_smmu_attach_dev(struct iommu_domain *domain,
 static int tegra_smmu_identity_attach(struct iommu_domain *identity_domain,
 				      struct device *dev)
 {
+	struct tegra_smmu_device *smmu_device = dev_iommu_priv_get(dev);
 	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	struct tegra_smmu_as *as;
 	struct tegra_smmu *smmu;
 	unsigned int index;
 
-	if (!fwspec)
-		return -ENODEV;
-
 	if (domain == identity_domain || !domain)
 		return 0;
 
 	as = to_smmu_as(domain);
 	smmu = as->smmu;
-	for (index = 0; index < fwspec->num_ids; index++) {
-		tegra_smmu_disable(smmu, fwspec->ids[index], as->id);
+	for (index = 0; index < smmu_device->num_ids; index++) {
+		tegra_smmu_disable(smmu, smmu_device->ids[index], as->id);
 		tegra_smmu_as_unprepare(smmu, as);
 	}
 	return 0;
@@ -811,77 +814,34 @@ static phys_addr_t tegra_smmu_iova_to_phys(struct iommu_domain *domain,
 	return SMMU_PFN_PHYS(pfn) + SMMU_OFFSET_IN_PAGE(iova);
 }
 
-static struct tegra_smmu *tegra_smmu_find(struct device_node *np)
+static struct iommu_device *
+tegra_smmu_probe_device(struct iommu_probe_info *pinf)
 {
-	struct platform_device *pdev;
-	struct tegra_mc *mc;
+	struct tegra_smmu_device *smmu_device;
+	struct tegra_smmu *smmu;
 
-	pdev = of_find_device_by_node(np);
-	if (!pdev)
-		return NULL;
+	iommu_of_allow_bus_probe(pinf);
+	smmu = iommu_of_get_single_iommu(pinf, &tegra_smmu_ops, 1,
+					 struct tegra_smmu, iommu);
+	if (IS_ERR(smmu))
+		return ERR_CAST(smmu);
 
-	mc = platform_get_drvdata(pdev);
-	if (!mc) {
-		put_device(&pdev->dev);
-		return NULL;
-	}
-
-	return mc->smmu;
-}
-
-static int tegra_smmu_configure(struct tegra_smmu *smmu, struct device *dev,
-				struct of_phandle_args *args)
-{
-	const struct iommu_ops *ops = smmu->iommu.ops;
-	int err;
-
-	err = iommu_fwspec_init(dev, &dev->of_node->fwnode, ops);
-	if (err < 0) {
-		dev_err(dev, "failed to initialize fwspec: %d\n", err);
-		return err;
-	}
-
-	err = ops->of_xlate(dev, args);
-	if (err < 0) {
-		dev_err(dev, "failed to parse SW group ID: %d\n", err);
-		iommu_fwspec_free(dev);
-		return err;
-	}
-
-	return 0;
-}
-
-static struct iommu_device *tegra_smmu_probe_device(struct device *dev)
-{
-	struct device_node *np = dev->of_node;
-	struct tegra_smmu *smmu = NULL;
-	struct of_phandle_args args;
-	unsigned int index = 0;
-	int err;
-
-	while (of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index,
-					  &args) == 0) {
-		smmu = tegra_smmu_find(args.np);
-		if (smmu) {
-			err = tegra_smmu_configure(smmu, dev, &args);
-
-			if (err < 0) {
-				of_node_put(args.np);
-				return ERR_PTR(err);
-			}
-		}
-
-		of_node_put(args.np);
-		index++;
-	}
-
-	smmu = dev_iommu_priv_get(dev);
-	if (!smmu)
-		return ERR_PTR(-ENODEV);
+	smmu_device = iommu_fw_alloc_per_device_ids(pinf, smmu_device);
+	if (IS_ERR(smmu_device))
+		return ERR_CAST(smmu_device);
+	smmu_device->smmu = smmu;
 
+	dev_iommu_priv_set(pinf->dev, smmu_device);
 	return &smmu->iommu;
 }
 
+static void tegra_smmu_release_device(struct device *dev)
+{
+	struct tegra_smmu_device *smmu_device = dev_iommu_priv_get(dev);
+
+	kfree(smmu_device);
+}
+
 static const struct tegra_smmu_group_soc *
 tegra_smmu_find_group(struct tegra_smmu *smmu, unsigned int swgroup)
 {
@@ -907,10 +867,10 @@ static void tegra_smmu_group_release(void *iommu_data)
 
 static struct iommu_group *tegra_smmu_device_group(struct device *dev)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-	struct tegra_smmu *smmu = dev_iommu_priv_get(dev);
+	struct tegra_smmu_device *smmu_device = dev_iommu_priv_get(dev);
+	struct tegra_smmu *smmu = smmu_device->smmu;
 	const struct tegra_smmu_group_soc *soc;
-	unsigned int swgroup = fwspec->ids[0];
+	unsigned int swgroup = smmu_device->ids[0];
 	struct tegra_smmu_group *group;
 	struct iommu_group *grp;
 
@@ -958,27 +918,6 @@ static struct iommu_group *tegra_smmu_device_group(struct device *dev)
 	return group->group;
 }
 
-static int tegra_smmu_of_xlate(struct device *dev,
-			       struct of_phandle_args *args)
-{
-	struct platform_device *iommu_pdev = of_find_device_by_node(args->np);
-	struct tegra_mc *mc = platform_get_drvdata(iommu_pdev);
-	u32 id = args->args[0];
-
-	/*
-	 * Note: we are here releasing the reference of &iommu_pdev->dev, which
-	 * is mc->dev. Although some functions in tegra_smmu_ops may keep using
-	 * its private data beyond this point, it's still safe to do so because
-	 * the SMMU parent device is the same as the MC, so the reference count
-	 * isn't strictly necessary.
-	 */
-	put_device(&iommu_pdev->dev);
-
-	dev_iommu_priv_set(dev, mc->smmu);
-
-	return iommu_fwspec_add_ids(dev, &id, 1);
-}
-
 static int tegra_smmu_def_domain_type(struct device *dev)
 {
 	/*
@@ -991,11 +930,11 @@ static int tegra_smmu_def_domain_type(struct device *dev)
 
 static bool tegra_smmu_get_stream_id(struct device *dev, u32 *stream_id)
 {
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct tegra_smmu_device *smmu_device = dev_iommu_priv_get(dev);
 
-	if (fwspec->num_ids != 1)
+	if (smmu_device->num_ids != 1)
 		return false;
-	*stream_id = fwspec->ids[0] & 0xffff;
+	*stream_id = smmu_device->ids[0] & 0xffff;
 	return true;
 }
 
@@ -1003,9 +942,10 @@ static const struct iommu_ops tegra_smmu_ops = {
 	.identity_domain = &tegra_smmu_identity_domain,
 	.def_domain_type = &tegra_smmu_def_domain_type,
 	.domain_alloc_paging = tegra_smmu_domain_alloc_paging,
-	.probe_device = tegra_smmu_probe_device,
+	.probe_device_pinf = tegra_smmu_probe_device,
+	.release_device = tegra_smmu_release_device,
 	.device_group = tegra_smmu_device_group,
-	.of_xlate = tegra_smmu_of_xlate,
+	.of_xlate = iommu_dummy_of_xlate,
 	.tegra_dev_iommu_get_stream_id = tegra_smmu_get_stream_id,
 	.pgsize_bitmap = SZ_4K,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
-- 
2.42.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

  parent reply	other threads:[~2023-11-30  1:10 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-30  1:10 [PATCH 00/30] Make a new API for drivers to use to get their FW Jason Gunthorpe
2023-11-30  1:10 ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 01/30] iommu/of: Make a of_iommu_for_each_id() Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 02/30] ACPI: VIOT: Make a viot_iommu_for_each_id() Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30 13:22   ` Rafael J. Wysocki
2023-11-30 13:22     ` Rafael J. Wysocki
2023-11-30  1:10 ` [PATCH 03/30] ACPI: IORT: Make a iort_iommu_for_each_id() Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30 13:21   ` Rafael J. Wysocki
2023-11-30 13:21     ` Rafael J. Wysocki
2023-11-30  1:10 ` [PATCH 04/30] ACPI: IORT: Remove fwspec from the reserved region code Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30 13:23   ` Rafael J. Wysocki
2023-11-30 13:23     ` Rafael J. Wysocki
2023-11-30  1:10 ` [PATCH 05/30] iommu: Add iommu_probe_info Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 06/30] iommu: Make iommu_ops_from_fwnode() return the iommu_device Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 07/30] iommu/of: Call of_iommu_get_resv_regions() directly Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 08/30] iommu/of: Add iommu_of_get_single_iommu() Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 09/30] iommu/rockchip: Move to iommu_of_get_single_iommu() Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 10/30] iommu/sprd: " Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 11/30] iommu/sun50i: " Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 12/30] iommu/of: Add iommu_of_xlate() Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 13/30] iommu/dart: Move to iommu_of_xlate() Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 14/30] iommu/exynos: " Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 15/30] iommu/msm: " Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 16/30] iommu/tegra: Route tegra_dev_iommu_get_stream_id() through an op Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 17/30] iommu: Add iommu_fw_alloc_per_device_ids() Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` Jason Gunthorpe [this message]
2023-11-30  1:10   ` [PATCH 18/30] iommu/tegra: Move to iommu_fw_alloc_per_device_ids() Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 19/30] iommu/mtk: " Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 20/30] iommu/ipmmu-vmsa: " Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 21/30] iommu/mtk_v1: " Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 22/30] iommu/qcom: " Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 23/30] iommu/viot: Add iommu_viot_get_single_iommu() Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 24/30] iommu/virtio: Move to iommu_fw_alloc_per_device_ids() Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 25/30] iommu/iort: Add iommu_iort_get_single_iommu() Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 26/30] iommu/arm-smmu-v3: Move to iommu_fw_alloc_per_device_ids() Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 27/30] iommu/arm-smmu: Move to iommu_of_xlate() Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 28/30] iommu: Call all drivers if there is no fwspec Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 29/30] iommu: Check for EPROBE_DEFER using the new FW parsers Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe
2023-11-30  1:10 ` [PATCH 30/30] iommu: Remove fwspec and related Jason Gunthorpe
2023-11-30  1:10   ` Jason Gunthorpe

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=18-v1-f82a05539a64+5042-iommu_fwspec_p2_jgg@nvidia.com \
    --to=jgg@nvidia.com \
    --cc=acpica-devel@lists.linux.dev \
    --cc=agross@kernel.org \
    --cc=alim.akhtar@samsung.com \
    --cc=alyssa@rosenzweig.io \
    --cc=andersson@kernel.org \
    --cc=andre.draszik@linaro.org \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=asahi@lists.linux.dev \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=devicetree@vger.kernel.org \
    --cc=frowand.list@gmail.com \
    --cc=guohanjun@huawei.com \
    --cc=gustavoars@kernel.org \
    --cc=heiko@sntech.de \
    --cc=iommu@lists.linux.dev \
    --cc=jean-philippe@linaro.org \
    --cc=jernej.skrabec@gmail.com \
    --cc=jonathanh@nvidia.com \
    --cc=joro@8bytes.org \
    --cc=keescook@chromium.org \
    --cc=konrad.dybcio@linaro.org \
    --cc=krzysztof.kozlowski@linaro.org \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=linux-sunxi@lists.linux.dev \
    --cc=linux-tegra@vger.kernel.org \
    --cc=lpieralisi@kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=marcan@marcan.st \
    --cc=matthias.bgg@gmail.com \
    --cc=orsonzhai@gmail.com \
    --cc=patches@lists.linux.dev \
    --cc=rafael@kernel.org \
    --cc=robdclark@gmail.com \
    --cc=robert.moore@intel.com \
    --cc=robh+dt@kernel.org \
    --cc=robin.murphy@arm.com \
    --cc=samuel@sholland.org \
    --cc=sudeep.holla@arm.com \
    --cc=sven@svenpeter.dev \
    --cc=thierry.reding@gmail.com \
    --cc=vdumpa@nvidia.com \
    --cc=virtualization@lists.linux.dev \
    --cc=wens@csie.org \
    --cc=will@kernel.org \
    --cc=yong.wu@mediatek.com \
    --cc=zhang.lyra@gmail.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.