iommu/exynos: Fix driver initialization sequence
Registering a SYSMMU platform driver might directly trigger initializing IOMMU domains and performing the initial mappings. Also the IOMMU core might use the IOMMU hardware once it has been registered with iommu_device_register() function. Ensure that all driver resources are allocated and initialized before the driver advertise its presence to the platform bus and the IOMMU subsystem. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org> Link: https://lore.kernel.org/r/20221110154407.26531-1-m.szyprowski@samsung.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
30a0b95b13
commit
bbc4d205d9
|
@ -708,10 +708,6 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = iommu_device_register(&data->iommu, &exynos_iommu_ops, dev);
|
||||
if (ret)
|
||||
goto err_iommu_register;
|
||||
|
||||
platform_set_drvdata(pdev, data);
|
||||
|
||||
if (PG_ENT_SHIFT < 0) {
|
||||
|
@ -743,11 +739,13 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
|
|||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
ret = iommu_device_register(&data->iommu, &exynos_iommu_ops, dev);
|
||||
if (ret)
|
||||
goto err_dma_set_mask;
|
||||
|
||||
return 0;
|
||||
|
||||
err_dma_set_mask:
|
||||
iommu_device_unregister(&data->iommu);
|
||||
err_iommu_register:
|
||||
iommu_device_sysfs_remove(&data->iommu);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1432,12 +1430,6 @@ static int __init exynos_iommu_init(void)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = platform_driver_register(&exynos_sysmmu_driver);
|
||||
if (ret) {
|
||||
pr_err("%s: Failed to register driver\n", __func__);
|
||||
goto err_reg_driver;
|
||||
}
|
||||
|
||||
zero_lv2_table = kmem_cache_zalloc(lv2table_kmem_cache, GFP_KERNEL);
|
||||
if (zero_lv2_table == NULL) {
|
||||
pr_err("%s: Failed to allocate zero level2 page table\n",
|
||||
|
@ -1446,10 +1438,16 @@ static int __init exynos_iommu_init(void)
|
|||
goto err_zero_lv2;
|
||||
}
|
||||
|
||||
ret = platform_driver_register(&exynos_sysmmu_driver);
|
||||
if (ret) {
|
||||
pr_err("%s: Failed to register driver\n", __func__);
|
||||
goto err_reg_driver;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_zero_lv2:
|
||||
platform_driver_unregister(&exynos_sysmmu_driver);
|
||||
err_reg_driver:
|
||||
platform_driver_unregister(&exynos_sysmmu_driver);
|
||||
err_zero_lv2:
|
||||
kmem_cache_destroy(lv2table_kmem_cache);
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue