| From 4e758c6bbbc3ba79dad00069f40b0f99f5c70d19 Mon Sep 17 00:00:00 2001 |
| From: Magnus Damm <damm+renesas@opensource.se> |
| Date: Mon, 16 Oct 2017 21:29:57 +0900 |
| Subject: [PATCH 0102/1795] iommu/ipmmu-vmsa: Make use of IOMMU_OF_DECLARE() |
| |
| Hook up IOMMU_OF_DECLARE() support in case CONFIG_IOMMU_DMA |
| is enabled. The only current supported case for 32-bit ARM |
| is disabled, however for 64-bit ARM usage of OF is required. |
| |
| Signed-off-by: Magnus Damm <damm+renesas@opensource.se> |
| Signed-off-by: Alex Williamson <alex.williamson@redhat.com> |
| (cherry picked from commit cda52fcd999f389c6f24f079910a62e53912d411) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> |
| --- |
| drivers/iommu/ipmmu-vmsa.c | 50 +++++++++++++++++++++++++++++++------- |
| 1 file changed, 41 insertions(+), 9 deletions(-) |
| |
| diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c |
| index c70efd80f740..9cde61970bb5 100644 |
| --- a/drivers/iommu/ipmmu-vmsa.c |
| +++ b/drivers/iommu/ipmmu-vmsa.c |
| @@ -20,6 +20,7 @@ |
| #include <linux/module.h> |
| #include <linux/of.h> |
| #include <linux/of_device.h> |
| +#include <linux/of_iommu.h> |
| #include <linux/of_platform.h> |
| #include <linux/platform_device.h> |
| #include <linux/sizes.h> |
| @@ -962,17 +963,30 @@ static int ipmmu_probe(struct platform_device *pdev) |
| ipmmu_device_reset(mmu); |
| } |
| |
| - ret = iommu_device_sysfs_add(&mmu->iommu, &pdev->dev, NULL, |
| - dev_name(&pdev->dev)); |
| - if (ret) |
| - return ret; |
| + /* |
| + * Register the IPMMU to the IOMMU subsystem in the following cases: |
| + * - R-Car Gen2 IPMMU (all devices registered) |
| + * - R-Car Gen3 IPMMU (leaf devices only - skip root IPMMU-MM device) |
| + */ |
| + if (!mmu->features->has_cache_leaf_nodes || !ipmmu_is_root(mmu)) { |
| + ret = iommu_device_sysfs_add(&mmu->iommu, &pdev->dev, NULL, |
| + dev_name(&pdev->dev)); |
| + if (ret) |
| + return ret; |
| |
| - iommu_device_set_ops(&mmu->iommu, &ipmmu_ops); |
| - iommu_device_set_fwnode(&mmu->iommu, &pdev->dev.of_node->fwnode); |
| + iommu_device_set_ops(&mmu->iommu, &ipmmu_ops); |
| + iommu_device_set_fwnode(&mmu->iommu, |
| + &pdev->dev.of_node->fwnode); |
| |
| - ret = iommu_device_register(&mmu->iommu); |
| - if (ret) |
| - return ret; |
| + ret = iommu_device_register(&mmu->iommu); |
| + if (ret) |
| + return ret; |
| + |
| +#if defined(CONFIG_IOMMU_DMA) |
| + if (!iommu_present(&platform_bus_type)) |
| + bus_set_iommu(&platform_bus_type, &ipmmu_ops); |
| +#endif |
| + } |
| |
| /* |
| * We can't create the ARM mapping here as it requires the bus to have |
| @@ -1010,15 +1024,22 @@ static struct platform_driver ipmmu_driver = { |
| |
| static int __init ipmmu_init(void) |
| { |
| + static bool setup_done; |
| int ret; |
| |
| + if (setup_done) |
| + return 0; |
| + |
| ret = platform_driver_register(&ipmmu_driver); |
| if (ret < 0) |
| return ret; |
| |
| +#if defined(CONFIG_ARM) && !defined(CONFIG_IOMMU_DMA) |
| if (!iommu_present(&platform_bus_type)) |
| bus_set_iommu(&platform_bus_type, &ipmmu_ops); |
| +#endif |
| |
| + setup_done = true; |
| return 0; |
| } |
| |
| @@ -1030,6 +1051,17 @@ static void __exit ipmmu_exit(void) |
| subsys_initcall(ipmmu_init); |
| module_exit(ipmmu_exit); |
| |
| +#ifdef CONFIG_IOMMU_DMA |
| +static int __init ipmmu_vmsa_iommu_of_setup(struct device_node *np) |
| +{ |
| + ipmmu_init(); |
| + return 0; |
| +} |
| + |
| +IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "renesas,ipmmu-vmsa", |
| + ipmmu_vmsa_iommu_of_setup); |
| +#endif |
| + |
| MODULE_DESCRIPTION("IOMMU API for Renesas VMSA-compatible IPMMU"); |
| MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); |
| MODULE_LICENSE("GPL v2"); |
| -- |
| 2.19.0 |
| |