msm: Make iommu domains platform devices
Information about the layout of iommu domains is a device
specific option. Convert the iommu domain information
into a platform driver with a corresponding platform device.
This allows different devices to have different layouts as
needed.
Change-Id: I6bf4162476143daabe16a2f5de3b655ae4377902
Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index d33a71f..a2e2080 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1971,6 +1971,7 @@
&apq_cpudai_slim_4_rx,
&apq_cpudai_slim_4_tx,
&msm8960_gemini_device,
+ &apq8064_iommu_domain_device,
};
static struct platform_device *sim_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 4327fd9..24e6a79 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1791,6 +1791,7 @@
&msm_bus_8930_sys_fpb,
&msm_bus_8930_cpss_fpb,
&msm8960_device_cache_erp,
+ &msm8930_iommu_domain_device,
};
static struct platform_device *cdp_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 45ebcaa..934f4a0 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2589,6 +2589,7 @@
#ifdef CONFIG_MSM_CACHE_DUMP
&msm_cache_dump_device,
#endif
+ &msm8960_iommu_domain_device,
};
static struct platform_device *sim_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 39eddfa..aaa5bfb 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -40,6 +40,7 @@
#include "rpm_stats.h"
#include "rpm_log.h"
#include <mach/mpm.h>
+#include <mach/iommu_domains.h>
/* Address of GSBI blocks */
#define MSM_GSBI1_PHYS 0x12440000
@@ -2249,3 +2250,161 @@
.num_resources = ARRAY_SIZE(msm_etm_resources),
.resource = msm_etm_resources,
};
+
+struct msm_iommu_domain_name apq8064_iommu_ctx_names[] = {
+ /* Camera */
+ {
+ .name = "vpe_src",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "vpe_dst",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "vfe_imgwr",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "vfe_misc",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "ijpeg_src",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "ijpeg_dst",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "jpegd_src",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "jpegd_dst",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Rotator */
+ {
+ .name = "rot_src",
+ .domain = ROTATOR_DOMAIN,
+ },
+ /* Rotator */
+ {
+ .name = "rot_dst",
+ .domain = ROTATOR_DOMAIN,
+ },
+ /* Video */
+ {
+ .name = "vcodec_a_mm1",
+ .domain = VIDEO_DOMAIN,
+ },
+ /* Video */
+ {
+ .name = "vcodec_b_mm2",
+ .domain = VIDEO_DOMAIN,
+ },
+ /* Video */
+ {
+ .name = "vcodec_a_stream",
+ .domain = VIDEO_DOMAIN,
+ },
+};
+
+static struct mem_pool apq8064_video_pools[] = {
+ /*
+ * Video hardware has the following requirements:
+ * 1. All video addresses used by the video hardware must be at a higher
+ * address than video firmware address.
+ * 2. Video hardware can only access a range of 256MB from the base of
+ * the video firmware.
+ */
+ [VIDEO_FIRMWARE_POOL] =
+ /* Low addresses, intended for video firmware */
+ {
+ .paddr = SZ_128K,
+ .size = SZ_16M - SZ_128K,
+ },
+ [VIDEO_MAIN_POOL] =
+ /* Main video pool */
+ {
+ .paddr = SZ_16M,
+ .size = SZ_256M - SZ_16M,
+ },
+ [GEN_POOL] =
+ /* Remaining address space up to 2G */
+ {
+ .paddr = SZ_256M,
+ .size = SZ_2G - SZ_256M,
+ },
+};
+
+static struct mem_pool apq8064_camera_pools[] = {
+ [GEN_POOL] =
+ /* One address space for camera */
+ {
+ .paddr = SZ_128K,
+ .size = SZ_2G - SZ_128K,
+ },
+};
+
+static struct mem_pool apq8064_display_pools[] = {
+ [GEN_POOL] =
+ /* One address space for display */
+ {
+ .paddr = SZ_128K,
+ .size = SZ_2G - SZ_128K,
+ },
+};
+
+static struct mem_pool apq8064_rotator_pools[] = {
+ [GEN_POOL] =
+ /* One address space for rotator */
+ {
+ .paddr = SZ_128K,
+ .size = SZ_2G - SZ_128K,
+ },
+};
+
+static struct msm_iommu_domain apq8064_iommu_domains[] = {
+ [VIDEO_DOMAIN] = {
+ .iova_pools = apq8064_video_pools,
+ .npools = ARRAY_SIZE(apq8064_video_pools),
+ },
+ [CAMERA_DOMAIN] = {
+ .iova_pools = apq8064_camera_pools,
+ .npools = ARRAY_SIZE(apq8064_camera_pools),
+ },
+ [DISPLAY_DOMAIN] = {
+ .iova_pools = apq8064_display_pools,
+ .npools = ARRAY_SIZE(apq8064_display_pools),
+ },
+ [ROTATOR_DOMAIN] = {
+ .iova_pools = apq8064_rotator_pools,
+ .npools = ARRAY_SIZE(apq8064_rotator_pools),
+ },
+};
+
+struct iommu_domains_pdata apq8064_iommu_domain_pdata = {
+ .domains = apq8064_iommu_domains,
+ .ndomains = ARRAY_SIZE(apq8064_iommu_domains),
+ .domain_names = apq8064_iommu_ctx_names,
+ .nnames = ARRAY_SIZE(apq8064_iommu_ctx_names),
+ .domain_alloc_flags = 0,
+};
+
+struct platform_device apq8064_iommu_domain_device = {
+ .name = "iommu_domains",
+ .id = -1,
+ .dev = {
+ .platform_data = &apq8064_iommu_domain_pdata,
+ },
+};
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index 85e927e..b7048db 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -22,6 +22,7 @@
#include <mach/msm_bus_board.h>
#include <mach/board.h>
#include <mach/socinfo.h>
+#include <mach/iommu_domains.h>
#include "devices.h"
#include "rpm_log.h"
@@ -628,3 +629,161 @@
}
platform_add_devices(vidc_device, ARRAY_SIZE(vidc_device));
}
+
+struct msm_iommu_domain_name msm8930_iommu_ctx_names[] = {
+ /* Camera */
+ {
+ .name = "vpe_src",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "vpe_dst",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "vfe_imgwr",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "vfe_misc",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "ijpeg_src",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "ijpeg_dst",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "jpegd_src",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "jpegd_dst",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Rotator */
+ {
+ .name = "rot_src",
+ .domain = ROTATOR_DOMAIN,
+ },
+ /* Rotator */
+ {
+ .name = "rot_dst",
+ .domain = ROTATOR_DOMAIN,
+ },
+ /* Video */
+ {
+ .name = "vcodec_a_mm1",
+ .domain = VIDEO_DOMAIN,
+ },
+ /* Video */
+ {
+ .name = "vcodec_b_mm2",
+ .domain = VIDEO_DOMAIN,
+ },
+ /* Video */
+ {
+ .name = "vcodec_a_stream",
+ .domain = VIDEO_DOMAIN,
+ },
+};
+
+static struct mem_pool msm8930_video_pools[] = {
+ /*
+ * Video hardware has the following requirements:
+ * 1. All video addresses used by the video hardware must be at a higher
+ * address than video firmware address.
+ * 2. Video hardware can only access a range of 256MB from the base of
+ * the video firmware.
+ */
+ [VIDEO_FIRMWARE_POOL] =
+ /* Low addresses, intended for video firmware */
+ {
+ .paddr = SZ_128K,
+ .size = SZ_16M - SZ_128K,
+ },
+ [VIDEO_MAIN_POOL] =
+ /* Main video pool */
+ {
+ .paddr = SZ_16M,
+ .size = SZ_256M - SZ_16M,
+ },
+ [GEN_POOL] =
+ /* Remaining address space up to 2G */
+ {
+ .paddr = SZ_256M,
+ .size = SZ_2G - SZ_256M,
+ },
+};
+
+static struct mem_pool msm8930_camera_pools[] = {
+ [GEN_POOL] =
+ /* One address space for camera */
+ {
+ .paddr = SZ_128K,
+ .size = SZ_2G - SZ_128K,
+ },
+};
+
+static struct mem_pool msm8930_display_pools[] = {
+ [GEN_POOL] =
+ /* One address space for display */
+ {
+ .paddr = SZ_128K,
+ .size = SZ_2G - SZ_128K,
+ },
+};
+
+static struct mem_pool msm8930_rotator_pools[] = {
+ [GEN_POOL] =
+ /* One address space for rotator */
+ {
+ .paddr = SZ_128K,
+ .size = SZ_2G - SZ_128K,
+ },
+};
+
+static struct msm_iommu_domain msm8930_iommu_domains[] = {
+ [VIDEO_DOMAIN] = {
+ .iova_pools = msm8930_video_pools,
+ .npools = ARRAY_SIZE(msm8930_video_pools),
+ },
+ [CAMERA_DOMAIN] = {
+ .iova_pools = msm8930_camera_pools,
+ .npools = ARRAY_SIZE(msm8930_camera_pools),
+ },
+ [DISPLAY_DOMAIN] = {
+ .iova_pools = msm8930_display_pools,
+ .npools = ARRAY_SIZE(msm8930_display_pools),
+ },
+ [ROTATOR_DOMAIN] = {
+ .iova_pools = msm8930_rotator_pools,
+ .npools = ARRAY_SIZE(msm8930_rotator_pools),
+ },
+};
+
+struct iommu_domains_pdata msm8930_iommu_domain_pdata = {
+ .domains = msm8930_iommu_domains,
+ .ndomains = ARRAY_SIZE(msm8930_iommu_domains),
+ .domain_names = msm8930_iommu_ctx_names,
+ .nnames = ARRAY_SIZE(msm8930_iommu_ctx_names),
+ .domain_alloc_flags = 0,
+};
+
+struct platform_device msm8930_iommu_domain_device = {
+ .name = "iommu_domains",
+ .id = -1,
+ .dev = {
+ .platform_data = &msm8930_iommu_domain_pdata,
+ },
+};
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 894c13f..8df1d7a 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -47,6 +47,7 @@
#include "pil-q6v4.h"
#include "scm-pas.h"
#include <mach/msm_dcvs.h>
+#include <mach/iommu_domains.h>
#ifdef CONFIG_MSM_MPM
#include <mach/mpm.h>
@@ -3343,3 +3344,161 @@
.num_resources = ARRAY_SIZE(msm_cache_erp_resources),
.resource = msm_cache_erp_resources,
};
+
+struct msm_iommu_domain_name msm8960_iommu_ctx_names[] = {
+ /* Camera */
+ {
+ .name = "vpe_src",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "vpe_dst",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "vfe_imgwr",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "vfe_misc",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "ijpeg_src",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "ijpeg_dst",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "jpegd_src",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Camera */
+ {
+ .name = "jpegd_dst",
+ .domain = CAMERA_DOMAIN,
+ },
+ /* Rotator */
+ {
+ .name = "rot_src",
+ .domain = ROTATOR_DOMAIN,
+ },
+ /* Rotator */
+ {
+ .name = "rot_dst",
+ .domain = ROTATOR_DOMAIN,
+ },
+ /* Video */
+ {
+ .name = "vcodec_a_mm1",
+ .domain = VIDEO_DOMAIN,
+ },
+ /* Video */
+ {
+ .name = "vcodec_b_mm2",
+ .domain = VIDEO_DOMAIN,
+ },
+ /* Video */
+ {
+ .name = "vcodec_a_stream",
+ .domain = VIDEO_DOMAIN,
+ },
+};
+
+static struct mem_pool msm8960_video_pools[] = {
+ /*
+ * Video hardware has the following requirements:
+ * 1. All video addresses used by the video hardware must be at a higher
+ * address than video firmware address.
+ * 2. Video hardware can only access a range of 256MB from the base of
+ * the video firmware.
+ */
+ [VIDEO_FIRMWARE_POOL] =
+ /* Low addresses, intended for video firmware */
+ {
+ .paddr = SZ_128K,
+ .size = SZ_16M - SZ_128K,
+ },
+ [VIDEO_MAIN_POOL] =
+ /* Main video pool */
+ {
+ .paddr = SZ_16M,
+ .size = SZ_256M - SZ_16M,
+ },
+ [GEN_POOL] =
+ /* Remaining address space up to 2G */
+ {
+ .paddr = SZ_256M,
+ .size = SZ_2G - SZ_256M,
+ },
+};
+
+static struct mem_pool msm8960_camera_pools[] = {
+ [GEN_POOL] =
+ /* One address space for camera */
+ {
+ .paddr = SZ_128K,
+ .size = SZ_2G - SZ_128K,
+ },
+};
+
+static struct mem_pool msm8960_display_pools[] = {
+ [GEN_POOL] =
+ /* One address space for display */
+ {
+ .paddr = SZ_128K,
+ .size = SZ_2G - SZ_128K,
+ },
+};
+
+static struct mem_pool msm8960_rotator_pools[] = {
+ [GEN_POOL] =
+ /* One address space for rotator */
+ {
+ .paddr = SZ_128K,
+ .size = SZ_2G - SZ_128K,
+ },
+};
+
+static struct msm_iommu_domain msm8960_iommu_domains[] = {
+ [VIDEO_DOMAIN] = {
+ .iova_pools = msm8960_video_pools,
+ .npools = ARRAY_SIZE(msm8960_video_pools),
+ },
+ [CAMERA_DOMAIN] = {
+ .iova_pools = msm8960_camera_pools,
+ .npools = ARRAY_SIZE(msm8960_camera_pools),
+ },
+ [DISPLAY_DOMAIN] = {
+ .iova_pools = msm8960_display_pools,
+ .npools = ARRAY_SIZE(msm8960_display_pools),
+ },
+ [ROTATOR_DOMAIN] = {
+ .iova_pools = msm8960_rotator_pools,
+ .npools = ARRAY_SIZE(msm8960_rotator_pools),
+ },
+};
+
+struct iommu_domains_pdata msm8960_iommu_domain_pdata = {
+ .domains = msm8960_iommu_domains,
+ .ndomains = ARRAY_SIZE(msm8960_iommu_domains),
+ .domain_names = msm8960_iommu_ctx_names,
+ .nnames = ARRAY_SIZE(msm8960_iommu_ctx_names),
+ .domain_alloc_flags = 0,
+};
+
+struct platform_device msm8960_iommu_domain_device = {
+ .name = "iommu_domains",
+ .id = -1,
+ .dev = {
+ .platform_data = &msm8960_iommu_domain_pdata,
+ },
+};
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 9e3ac63..5718fe0 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -373,5 +373,8 @@
extern struct platform_device msm_device_csic1;
extern struct platform_device msm_device_vfe;
extern struct platform_device msm_device_vpe;
-
extern struct platform_device mpq8064_device_qup_i2c_gsbi5;
+
+extern struct platform_device msm8960_iommu_domain_device;
+extern struct platform_device msm8930_iommu_domain_device;
+extern struct platform_device apq8064_iommu_domain_device;
diff --git a/arch/arm/mach-msm/include/mach/iommu_domains.h b/arch/arm/mach-msm/include/mach/iommu_domains.h
index 74e1115..52e70ec 100644
--- a/arch/arm/mach-msm/include/mach/iommu_domains.h
+++ b/arch/arm/mach-msm/include/mach/iommu_domains.h
@@ -13,6 +13,8 @@
#ifndef _ARCH_IOMMU_DOMAINS_H
#define _ARCH_IOMMU_DOMAINS_H
+#include <linux/memory_alloc.h>
+
enum {
VIDEO_DOMAIN,
CAMERA_DOMAIN,
@@ -27,6 +29,32 @@
GEN_POOL,
};
+struct msm_iommu_domain_name {
+ char *name;
+ int domain;
+};
+
+struct msm_iommu_domain {
+ /* iommu domain to map in */
+ struct iommu_domain *domain;
+ /* total number of allocations from this domain */
+ atomic_t allocation_cnt;
+ /* number of iova pools */
+ int npools;
+ /*
+ * array of gen_pools for allocating iovas.
+ * behavior is undefined if these overlap
+ */
+ struct mem_pool *iova_pools;
+};
+
+struct iommu_domains_pdata {
+ struct msm_iommu_domain *domains;
+ int ndomains;
+ struct msm_iommu_domain_name *domain_names;
+ int nnames;
+ unsigned int domain_alloc_flags;
+};
#if defined(CONFIG_MSM_IOMMU)
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index dbc1389..8f4af3b 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -13,6 +13,7 @@
#include <mach/msm_subsystem_map.h>
#include <linux/memory_alloc.h>
#include <linux/iommu.h>
+#include <linux/platform_device.h>
#include <linux/vmalloc.h>
#include <asm/sizes.h>
#include <asm/page.h>
@@ -24,166 +25,12 @@
/* dummy 4k for overmapping */
char iommu_dummy[2*PAGE_SIZE-4];
-struct msm_iommu_domain {
- /* iommu domain to map in */
- struct iommu_domain *domain;
- /* total number of allocations from this domain */
- atomic_t allocation_cnt;
- /* number of iova pools */
- int npools;
- /*
- * array of gen_pools for allocating iovas.
- * behavior is undefined if these overlap
- */
- struct mem_pool *iova_pools;
-
+struct msm_iommu_domain_state {
+ struct msm_iommu_domain *domains;
+ int ndomains;
};
-
-struct {
- char *name;
- int domain;
-} msm_iommu_ctx_names[] = {
- /* Camera */
- {
- .name = "vpe_src",
- .domain = CAMERA_DOMAIN,
- },
- /* Camera */
- {
- .name = "vpe_dst",
- .domain = CAMERA_DOMAIN,
- },
- /* Camera */
- {
- .name = "vfe_imgwr",
- .domain = CAMERA_DOMAIN,
- },
- /* Camera */
- {
- .name = "vfe_misc",
- .domain = CAMERA_DOMAIN,
- },
- /* Camera */
- {
- .name = "ijpeg_src",
- .domain = CAMERA_DOMAIN,
- },
- /* Camera */
- {
- .name = "ijpeg_dst",
- .domain = CAMERA_DOMAIN,
- },
- /* Camera */
- {
- .name = "jpegd_src",
- .domain = CAMERA_DOMAIN,
- },
- /* Camera */
- {
- .name = "jpegd_dst",
- .domain = CAMERA_DOMAIN,
- },
- /* Rotator */
- {
- .name = "rot_src",
- .domain = ROTATOR_DOMAIN,
- },
- /* Rotator */
- {
- .name = "rot_dst",
- .domain = ROTATOR_DOMAIN,
- },
- /* Video */
- {
- .name = "vcodec_a_mm1",
- .domain = VIDEO_DOMAIN,
- },
- /* Video */
- {
- .name = "vcodec_b_mm2",
- .domain = VIDEO_DOMAIN,
- },
- /* Video */
- {
- .name = "vcodec_a_stream",
- .domain = VIDEO_DOMAIN,
- },
-};
-
-static struct mem_pool video_pools[] = {
- /*
- * Video hardware has the following requirements:
- * 1. All video addresses used by the video hardware must be at a higher
- * address than video firmware address.
- * 2. Video hardware can only access a range of 256MB from the base of
- * the video firmware.
- */
- [VIDEO_FIRMWARE_POOL] =
- /* Low addresses, intended for video firmware */
- {
- .paddr = SZ_128K,
- .size = SZ_16M - SZ_128K,
- },
- [VIDEO_MAIN_POOL] =
- /* Main video pool */
- {
- .paddr = SZ_16M,
- .size = SZ_256M - SZ_16M,
- },
- [GEN_POOL] =
- /* Remaining address space up to 2G */
- {
- .paddr = SZ_256M,
- .size = SZ_2G - SZ_256M,
- },
-};
-
-static struct mem_pool camera_pools[] = {
- [GEN_POOL] =
- /* One address space for camera */
- {
- .paddr = SZ_128K,
- .size = SZ_2G - SZ_128K,
- },
-};
-
-static struct mem_pool display_pools[] = {
- [GEN_POOL] =
- /* One address space for display */
- {
- .paddr = SZ_128K,
- .size = SZ_2G - SZ_128K,
- },
-};
-
-static struct mem_pool rotator_pools[] = {
- [GEN_POOL] =
- /* One address space for rotator */
- {
- .paddr = SZ_128K,
- .size = SZ_2G - SZ_128K,
- },
-};
-
-static struct msm_iommu_domain msm_iommu_domains[] = {
- [VIDEO_DOMAIN] = {
- .iova_pools = video_pools,
- .npools = ARRAY_SIZE(video_pools),
- },
- [CAMERA_DOMAIN] = {
- .iova_pools = camera_pools,
- .npools = ARRAY_SIZE(camera_pools),
- },
- [DISPLAY_DOMAIN] = {
- .iova_pools = display_pools,
- .npools = ARRAY_SIZE(display_pools),
- },
- [ROTATOR_DOMAIN] = {
- .iova_pools = rotator_pools,
- .npools = ARRAY_SIZE(rotator_pools),
- },
-};
+static struct msm_iommu_domain_state domain_state;
int msm_iommu_map_extra(struct iommu_domain *domain,
unsigned long start_iova,
@@ -221,8 +68,8 @@
struct iommu_domain *msm_get_iommu_domain(int domain_num)
{
- if (domain_num >= 0 && domain_num < MAX_DOMAINS)
- return msm_iommu_domains[domain_num].domain;
+ if (domain_num >= 0 && domain_num < domain_state.ndomains)
+ return domain_state.domains[domain_num].domain;
else
return NULL;
}
@@ -235,13 +82,13 @@
struct mem_pool *pool;
unsigned long iova;
- if (iommu_domain >= MAX_DOMAINS)
+ if (iommu_domain >= domain_state.ndomains)
return 0;
- if (partition_no >= msm_iommu_domains[iommu_domain].npools)
+ if (partition_no >= domain_state.domains[iommu_domain].npools)
return 0;
- pool = &msm_iommu_domains[iommu_domain].iova_pools[partition_no];
+ pool = &domain_state.domains[iommu_domain].iova_pools[partition_no];
if (!pool->gpool)
return 0;
@@ -260,18 +107,18 @@
{
struct mem_pool *pool;
- if (iommu_domain >= MAX_DOMAINS) {
+ if (iommu_domain >= domain_state.ndomains) {
WARN(1, "Invalid domain %d\n", iommu_domain);
return;
}
- if (partition_no >= msm_iommu_domains[iommu_domain].npools) {
+ if (partition_no >= domain_state.domains[iommu_domain].npools) {
WARN(1, "Invalid partition %d for domain %d\n",
partition_no, iommu_domain);
return;
}
- pool = &msm_iommu_domains[iommu_domain].iova_pools[partition_no];
+ pool = &domain_state.domains[iommu_domain].iova_pools[partition_no];
if (!pool)
return;
@@ -282,20 +129,31 @@
int msm_use_iommu()
{
- return iommu_found();
+ /*
+ * If there are no domains, don't bother trying to use the iommu
+ */
+ return domain_state.ndomains && iommu_found();
}
-static int __init msm_subsystem_iommu_init(void)
+static int __init iommu_domain_probe(struct platform_device *pdev)
{
+ struct iommu_domains_pdata *p = pdev->dev.platform_data;
int i, j;
- for (i = 0; i < ARRAY_SIZE(msm_iommu_domains); i++) {
- msm_iommu_domains[i].domain = iommu_domain_alloc(0);
- if (!msm_iommu_domains[i].domain)
+ if (!p)
+ return -ENODEV;
+
+ domain_state.domains = p->domains;
+ domain_state.ndomains = p->ndomains;
+
+ for (i = 0; i < domain_state.ndomains; i++) {
+ domain_state.domains[i].domain = iommu_domain_alloc(
+ p->domain_alloc_flags);
+ if (!domain_state.domains[i].domain)
continue;
- for (j = 0; j < msm_iommu_domains[i].npools; j++) {
- struct mem_pool *pool = &msm_iommu_domains[i].
+ for (j = 0; j < domain_state.domains[i].npools; j++) {
+ struct mem_pool *pool = &domain_state.domains[i].
iova_pools[j];
mutex_init(&pool->pool_mutex);
if (pool->size) {
@@ -325,29 +183,41 @@
}
}
- for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_names); i++) {
+ for (i = 0; i < p->nnames; i++) {
int domain_idx;
struct device *ctx = msm_iommu_get_ctx(
- msm_iommu_ctx_names[i].name);
+ p->domain_names[i].name);
if (!ctx)
continue;
- domain_idx = msm_iommu_ctx_names[i].domain;
+ domain_idx = p->domain_names[i].domain;
- if (!msm_iommu_domains[domain_idx].domain)
+ if (!domain_state.domains[domain_idx].domain)
continue;
- if (iommu_attach_device(msm_iommu_domains[domain_idx].domain,
+ if (iommu_attach_device(domain_state.domains[domain_idx].domain,
ctx)) {
WARN(1, "%s: could not attach domain %d to context %s."
" iommu programming will not occur.\n",
__func__, domain_idx,
- msm_iommu_ctx_names[i].name);
+ p->domain_names[i].name);
continue;
}
}
return 0;
}
+
+static struct platform_driver iommu_domain_driver = {
+ .driver = {
+ .name = "iommu_domains",
+ .owner = THIS_MODULE
+ },
+};
+
+static int __init msm_subsystem_iommu_init(void)
+{
+ return platform_driver_probe(&iommu_domain_driver, iommu_domain_probe);
+}
device_initcall(msm_subsystem_iommu_init);