iommu/tegra-gart: Add support for struct iommu_device
Add a struct iommu_device to each tegra-gart and register it with the iommu-core. Also link devices added to the driver to their respective hardware iommus. Reviewed-by: Dmitry Osipenko <digetx@gmail.com> Tested-by: Dmitry Osipenko <digetx@gmail.com> Acked-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
0b480e4470
commit
c184ae83c8
1 changed files with 26 additions and 0 deletions
|
@ -61,6 +61,8 @@ struct gart_device {
|
||||||
struct list_head client;
|
struct list_head client;
|
||||||
spinlock_t client_lock; /* for client list */
|
spinlock_t client_lock; /* for client list */
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
|
||||||
|
struct iommu_device iommu; /* IOMMU Core handle */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gart_domain {
|
struct gart_domain {
|
||||||
|
@ -342,12 +344,16 @@ static int gart_iommu_add_device(struct device *dev)
|
||||||
return PTR_ERR(group);
|
return PTR_ERR(group);
|
||||||
|
|
||||||
iommu_group_put(group);
|
iommu_group_put(group);
|
||||||
|
|
||||||
|
iommu_device_link(&gart_handle->iommu, dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gart_iommu_remove_device(struct device *dev)
|
static void gart_iommu_remove_device(struct device *dev)
|
||||||
{
|
{
|
||||||
iommu_group_remove_device(dev);
|
iommu_group_remove_device(dev);
|
||||||
|
iommu_device_unlink(&gart_handle->iommu, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct iommu_ops gart_iommu_ops = {
|
static const struct iommu_ops gart_iommu_ops = {
|
||||||
|
@ -397,6 +403,7 @@ static int tegra_gart_probe(struct platform_device *pdev)
|
||||||
struct resource *res, *res_remap;
|
struct resource *res, *res_remap;
|
||||||
void __iomem *gart_regs;
|
void __iomem *gart_regs;
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (gart_handle)
|
if (gart_handle)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -423,6 +430,22 @@ static int tegra_gart_probe(struct platform_device *pdev)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = iommu_device_sysfs_add(&gart->iommu, &pdev->dev, NULL,
|
||||||
|
dev_name(&pdev->dev));
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "Failed to register IOMMU in sysfs\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
iommu_device_set_ops(&gart->iommu, &gart_iommu_ops);
|
||||||
|
|
||||||
|
ret = iommu_device_register(&gart->iommu);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "Failed to register IOMMU\n");
|
||||||
|
iommu_device_sysfs_remove(&gart->iommu);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
gart->dev = &pdev->dev;
|
gart->dev = &pdev->dev;
|
||||||
spin_lock_init(&gart->pte_lock);
|
spin_lock_init(&gart->pte_lock);
|
||||||
spin_lock_init(&gart->client_lock);
|
spin_lock_init(&gart->client_lock);
|
||||||
|
@ -449,6 +472,9 @@ static int tegra_gart_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct gart_device *gart = platform_get_drvdata(pdev);
|
struct gart_device *gart = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
iommu_device_unregister(&gart->iommu);
|
||||||
|
iommu_device_sysfs_remove(&gart->iommu);
|
||||||
|
|
||||||
writel(0, gart->regs + GART_CONFIG);
|
writel(0, gart->regs + GART_CONFIG);
|
||||||
if (gart->savedata)
|
if (gart->savedata)
|
||||||
vfree(gart->savedata);
|
vfree(gart->savedata);
|
||||||
|
|
Loading…
Add table
Reference in a new issue