[RFC 1/1] platform: IOMMU'able platform_device w/PLATFORM_ENABLE_IOMMU

From: Hiroshi Doyu
Date: Thu Mar 22 2012 - 10:06:27 EST


Introduced a new kernel config option, PLATFORM_ENABLE_IOMMU. With
this, all platform devices can be converted to be IOMMU'able if
platform_bus has non-null dma_iommu_map, where H/Ws always see its IO
virtual address and virt_to_phys() doesn't work from H/W POV.

Signed-off-by: Hiroshi Doyu <hdoyu@xxxxxxxxxx>
---
arch/arm/mm/dma-mapping.c | 7 +++++++
drivers/base/Kconfig | 4 ++++
drivers/base/platform.c | 17 +++++++++++++++--
drivers/iommu/Kconfig | 2 +-
include/linux/device.h | 5 ++++-
5 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 242289f..28ca7c2 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1899,6 +1899,13 @@ arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size,
mapping->order = order;
spin_lock_init(&mapping->lock);

+#ifdef CONFIG_PLATFORM_ENABLE_IOMMU
+ if (WARN_ON(bus->map))
+ goto err3;
+
+ bus->map = mapping;
+#endif
+
mapping->domain = iommu_domain_alloc(bus);
if (!mapping->domain)
goto err3;
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 3df339c..0f45311 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -308,4 +308,8 @@ config CMA_AREAS

endif

+config PLATFORM_ENABLE_IOMMU
+ bool "Make platform devices iommuable"
+ depends on IOMMU_API
+
endmenu
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index a1a7225..9eae3be 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -21,6 +21,8 @@
#include <linux/slab.h>
#include <linux/pm_runtime.h>

+#include <asm/dma-iommu.h>
+
#include "base.h"

#define to_platform_driver(drv) (container_of((drv), struct platform_driver, \
@@ -305,8 +307,19 @@ int platform_device_add(struct platform_device *pdev)
dev_name(&pdev->dev), dev_name(pdev->dev.parent));

ret = device_add(&pdev->dev);
- if (ret == 0)
- return ret;
+ if (ret)
+ goto failed;
+
+#ifdef CONFIG_PLATFORM_ENABLE_IOMMU
+ if (platform_bus_type.map && !pdev->dev.archdata.mapping) {
+ ret = arm_iommu_attach_device(&pdev->dev,
+ platform_bus_type.map);
+ if (ret)
+ goto failed;
+ }
+#endif
+
+ return 0;

failed:
while (--i >= 0) {
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index b736809..8b7eca1 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -164,7 +164,7 @@ config TEGRA_IOMMU_SMMU

config TEGRA_IOMMU_SMMU_LINEAR
bool "Physical RAM IOVA Liner Mapping Support"
- depends on TEGRA_IOMMU_SMMU
+ depends on TEGRA_IOMMU_SMMU && !PLATFORM_ENABLE_IOMMU
default y
help
Enables support for linear mapping between physical address
diff --git a/include/linux/device.h b/include/linux/device.h
index e339929..3dcb501 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -35,6 +35,7 @@ struct subsys_private;
struct bus_type;
struct device_node;
struct iommu_ops;
+struct dma_iommu_mapping;

struct bus_attribute {
struct attribute attr;
@@ -106,7 +107,9 @@ struct bus_type {
const struct dev_pm_ops *pm;

struct iommu_ops *iommu_ops;
-
+#ifdef CONFIG_PLATFORM_ENABLE_IOMMU
+ struct dma_iommu_mapping *map;
+#endif
struct subsys_private *p;
};
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/