Commit 6785eb91 authored by Joerg Roedel's avatar Joerg Roedel
Browse files

iommu/omap: Convert to probe/release_device() call-backs



Convert the OMAP IOMMU driver to use the probe_device() and
release_device() call-backs of iommu_ops, so that the iommu core code
does the group and sysfs setup.

Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
Link: https://lore.kernel.org/r/20200429133712.31431-30-joro@8bytes.org


Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent c822b37c
Loading
Loading
Loading
Loading
+13 −36
Original line number Diff line number Diff line
@@ -1640,15 +1640,13 @@ static phys_addr_t omap_iommu_iova_to_phys(struct iommu_domain *domain,
	return ret;
}

static int omap_iommu_add_device(struct device *dev)
static struct iommu_device *omap_iommu_probe_device(struct device *dev)
{
	struct omap_iommu_arch_data *arch_data, *tmp;
	struct platform_device *pdev;
	struct omap_iommu *oiommu;
	struct iommu_group *group;
	struct device_node *np;
	struct platform_device *pdev;
	int num_iommus, i;
	int ret;

	/*
	 * Allocate the archdata iommu structure for DT-based devices.
@@ -1657,7 +1655,7 @@ static int omap_iommu_add_device(struct device *dev)
	 * IOMMU users.
	 */
	if (!dev->of_node)
		return 0;
		return ERR_PTR(-ENODEV);

	/*
	 * retrieve the count of IOMMU nodes using phandle size as element size
@@ -1670,27 +1668,27 @@ static int omap_iommu_add_device(struct device *dev)

	arch_data = kcalloc(num_iommus + 1, sizeof(*arch_data), GFP_KERNEL);
	if (!arch_data)
		return -ENOMEM;
		return ERR_PTR(-ENOMEM);

	for (i = 0, tmp = arch_data; i < num_iommus; i++, tmp++) {
		np = of_parse_phandle(dev->of_node, "iommus", i);
		if (!np) {
			kfree(arch_data);
			return -EINVAL;
			return ERR_PTR(-EINVAL);
		}

		pdev = of_find_device_by_node(np);
		if (!pdev) {
			of_node_put(np);
			kfree(arch_data);
			return -ENODEV;
			return ERR_PTR(-ENODEV);
		}

		oiommu = platform_get_drvdata(pdev);
		if (!oiommu) {
			of_node_put(np);
			kfree(arch_data);
			return -EINVAL;
			return ERR_PTR(-EINVAL);
		}

		tmp->iommu_dev = oiommu;
@@ -1699,46 +1697,25 @@ static int omap_iommu_add_device(struct device *dev)
		of_node_put(np);
	}

	dev->archdata.iommu = arch_data;

	/*
	 * use the first IOMMU alone for the sysfs device linking.
	 * TODO: Evaluate if a single iommu_group needs to be
	 * maintained for both IOMMUs
	 */
	oiommu = arch_data->iommu_dev;
	ret = iommu_device_link(&oiommu->iommu, dev);
	if (ret) {
		kfree(arch_data);
		return ret;
	}

	dev->archdata.iommu = arch_data;

	/*
	 * IOMMU group initialization calls into omap_iommu_device_group, which
	 * needs a valid dev->archdata.iommu pointer
	 */
	group = iommu_group_get_for_dev(dev);
	if (IS_ERR(group)) {
		iommu_device_unlink(&oiommu->iommu, dev);
		dev->archdata.iommu = NULL;
		kfree(arch_data);
		return PTR_ERR(group);
	}
	iommu_group_put(group);

	return 0;
	return &oiommu->iommu;
}

static void omap_iommu_remove_device(struct device *dev)
static void omap_iommu_release_device(struct device *dev)
{
	struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;

	if (!dev->of_node || !arch_data)
		return;

	iommu_device_unlink(&arch_data->iommu_dev->iommu, dev);
	iommu_group_remove_device(dev);

	dev->archdata.iommu = NULL;
	kfree(arch_data);

@@ -1763,8 +1740,8 @@ static const struct iommu_ops omap_iommu_ops = {
	.map		= omap_iommu_map,
	.unmap		= omap_iommu_unmap,
	.iova_to_phys	= omap_iommu_iova_to_phys,
	.add_device	= omap_iommu_add_device,
	.remove_device	= omap_iommu_remove_device,
	.probe_device	= omap_iommu_probe_device,
	.release_device	= omap_iommu_release_device,
	.device_group	= omap_iommu_device_group,
	.pgsize_bitmap	= OMAP_IOMMU_PGSIZES,
};