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);