platform: IOMMU'able platform_device w/ PLATFORM_ENABLE_IOMMU
Hiroshi Doyu [Thu, 22 Mar 2012 14:06:27 +0000 (16:06 +0200)]
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.

Change-Id: Iafc4cac73624cfa0bb0f513febd7d91c59954268
Signed-off-by: Hiroshi Doyu <hdoyu@nvidia.com>

drivers/base/Kconfig
drivers/base/platform.c
drivers/iommu/Kconfig
include/linux/device.h

index 3df339c..0f45311 100644 (file)
@@ -308,4 +308,8 @@ config CMA_AREAS
 
 endif
 
+config PLATFORM_ENABLE_IOMMU
+        bool "Make platform devices iommuable"
+       depends on IOMMU_API
+
 endmenu
index a1a7225..9eae3be 100644 (file)
@@ -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) {
index b736809..8b7eca1 100644 (file)
@@ -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
index e339929..3dcb501 100644 (file)
@@ -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;
 };