Skip to content

Commit

Permalink
iommu/omap: Add minimal fwnode support
Browse files Browse the repository at this point in the history
The OMAP driver uses the generic "iommus" DT binding but is the final
holdout not implementing a corresponding .of_xlate method. Unfortunately
this now results in __iommu_probe_device() failing to find ops due to
client devices missing the expected IOMMU fwnode association. The legacy
DT parsing in omap_iommu_probe_device() could probably all be delegated
to generic code now, but for the sake of an immediate fix, just add a
minimal .of_xlate implementation to allow client fwspecs to be created
appropriately, and so the ops lookup to work again.

This means we also need to register the additional instances on DRA7 so
that of_iommu_xlate() doesn't defer indefinitely waiting for their ops
either, but we'll continue to hide them from sysfs just in case. This
also renders the bus_iommu_probe() call entirely redundant.

Reported-by: Beleswar Padhi <b-padhi@ti.com>
Link: https://lore.kernel.org/linux-iommu/0dbde87b-593f-4b14-8929-b78e189549ad@ti.com/
Reported-by: H. Nikolaus Schaller <hns@goldelico.com>
Link: https://lore.kernel.org/linux-media/A7C284A9-33A5-4E21-9B57-9C4C213CC13F@goldelico.com/
Fixes: 17de3f5 ("iommu: Retire bus ops")
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Tested-by: H. Nikolaus Schaller <hns@goldelico.com>
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Tested-by: Kevin Hilman <khilman@baylibre.com>
Tested-by: Beleswar Padhi <b-padhi@ti.com>
Link: https://lore.kernel.org/r/cfd766f96bc799e32b97f4664707adbcf99097b0.1730136799.git.robin.murphy@arm.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
  • Loading branch information
Robin Murphy authored and Joerg Roedel committed Oct 30, 2024
1 parent 8e929cb commit c9b4a31
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions drivers/iommu/omap-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1230,36 +1230,35 @@ static int omap_iommu_probe(struct platform_device *pdev)
if (err)
return err;

err = iommu_device_register(&obj->iommu, &omap_iommu_ops, &pdev->dev);
if (err)
goto out_sysfs;
obj->has_iommu_driver = true;
}

err = iommu_device_register(&obj->iommu, &omap_iommu_ops, &pdev->dev);
if (err)
goto out_sysfs;

pm_runtime_enable(obj->dev);

omap_iommu_debugfs_add(obj);

dev_info(&pdev->dev, "%s registered\n", obj->name);

/* Re-probe bus to probe device attached to this IOMMU */
bus_iommu_probe(&platform_bus_type);

return 0;

out_sysfs:
iommu_device_sysfs_remove(&obj->iommu);
if (obj->has_iommu_driver)
iommu_device_sysfs_remove(&obj->iommu);
return err;
}

static void omap_iommu_remove(struct platform_device *pdev)
{
struct omap_iommu *obj = platform_get_drvdata(pdev);

if (obj->has_iommu_driver) {
if (obj->has_iommu_driver)
iommu_device_sysfs_remove(&obj->iommu);
iommu_device_unregister(&obj->iommu);
}

iommu_device_unregister(&obj->iommu);

omap_iommu_debugfs_remove(obj);

Expand Down Expand Up @@ -1723,12 +1722,19 @@ static void omap_iommu_release_device(struct device *dev)

}

static int omap_iommu_of_xlate(struct device *dev, const struct of_phandle_args *args)
{
/* TODO: collect args->np to save re-parsing in probe above */
return 0;
}

static const struct iommu_ops omap_iommu_ops = {
.identity_domain = &omap_iommu_identity_domain,
.domain_alloc_paging = omap_iommu_domain_alloc_paging,
.probe_device = omap_iommu_probe_device,
.release_device = omap_iommu_release_device,
.device_group = generic_single_device_group,
.of_xlate = omap_iommu_of_xlate,
.pgsize_bitmap = OMAP_IOMMU_PGSIZES,
.default_domain_ops = &(const struct iommu_domain_ops) {
.attach_dev = omap_iommu_attach_dev,
Expand Down

0 comments on commit c9b4a31

Please sign in to comment.