iommu: msm: Refactor code to separate compilation

Modify the code and update makefile and defconfig to allow us to
only compile one of the two IOMMU drivers that we have. Only one of
the drivers are needed at the same time. This will ensure we are not
compiling and linking code that is not needed.

Change-Id: I7db69f873245e57bddab6625e0b04e2ed48f44b6
Signed-off-by: Olav Haugan <ohaugan@codeaurora.org>
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index aa69475..318b98f 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -14,12 +14,32 @@
 if IOMMU_SUPPORT
 
 # MSM IOMMU support
+
+# MSM_IOMMU always gets selected by whoever wants it.
 config MSM_IOMMU
-	bool "MSM IOMMU Support"
-	depends on ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8974 || ARCH_MPQ8092 || ARCH_MSM8610 || ARCH_MSM8226 || ARCH_APQ8084
+	bool
+
+# MSM IOMMUv0 support
+config MSM_IOMMU_V0
+	bool "MSM IOMMUv0 Support"
+	depends on ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8610
 	select IOMMU_API
+	select MSM_IOMMU
 	help
-	  Support for the IOMMUs found on certain Qualcomm SOCs.
+	  Support for the IOMMUs (v0) found on certain Qualcomm SOCs.
+	  These IOMMUs allow virtualization of the address space used by most
+	  cores within the multimedia subsystem.
+
+	  If unsure, say N here.
+
+# MSM IOMMUv1 support
+config MSM_IOMMU_V1
+	bool "MSM IOMMUv1 Support"
+	depends on ARCH_MSM8974 || ARCH_MPQ8092 || ARCH_MSM8226 || ARCH_APQ8084
+	select IOMMU_API
+	select MSM_IOMMU
+	help
+	  Support for the IOMMUs (v1) found on certain Qualcomm SOCs.
 	  These IOMMUs allow virtualization of the address space used by most
 	  cores within the multimedia subsystem.
 
@@ -28,7 +48,7 @@
 # MSM IOMMU CPU-GPU sync programming support
 config MSM_IOMMU_GPU_SYNC
 	bool "MSM IOMMU CPU-GPU Sync Support"
-	depends on (ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8930) && MSM_IOMMU && MSM_REMOTE_SPINLOCK_SFPB
+	depends on (ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8930) && MSM_IOMMU_V0 && MSM_REMOTE_SPINLOCK_SFPB
 	help
 	  Say Y here if you want to synchronize access to IOMMU configuration
 	  port between CPU and GPU. CPU will grab a remote spinlock before
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 096b53e..29a8b39 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -1,9 +1,14 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
-obj-$(CONFIG_MSM_IOMMU) += msm_iommu-v0.o msm_iommu_dev-v0.o
-ifdef CONFIG_OF
-obj-$(CONFIG_MSM_IOMMU) += msm_iommu-v1.o msm_iommu_dev-v1.o msm_iommu_pagetable.o msm_iommu_sec.o
+obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
+obj-$(CONFIG_MSM_IOMMU_V0) += msm_iommu-v0.o msm_iommu_dev-v0.o
+obj-$(CONFIG_MSM_IOMMU_V1) += msm_iommu-v1.o msm_iommu_dev-v1.o msm_iommu_pagetable.o msm_iommu_sec.o
+obj-$(CONFIG_MSM_IOMMU_PMON) += msm_iommu_perfmon.o
+ifdef CONFIG_MSM_IOMMU_V0
+obj-$(CONFIG_MSM_IOMMU_PMON) += msm_iommu_perfmon-v0.o
 endif
-obj-$(CONFIG_MSM_IOMMU_PMON) += msm_iommu_perfmon.o msm_iommu_perfmon-v0.o msm_iommu_perfmon-v1.o
+ifdef CONFIG_MSM_IOMMU_V1
+obj-$(CONFIG_MSM_IOMMU_PMON) += msm_iommu_perfmon-v1.o
+endif
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
 obj-$(CONFIG_DMAR_TABLE) += dmar.o
diff --git a/drivers/iommu/msm_iommu-v0.c b/drivers/iommu/msm_iommu-v0.c
index eadbd64..49bfdb8 100644
--- a/drivers/iommu/msm_iommu-v0.c
+++ b/drivers/iommu/msm_iommu-v0.c
@@ -52,10 +52,6 @@
 #define MSM_IOMMU_ATTR_CACHED_WB_NWA	0x2
 #define MSM_IOMMU_ATTR_CACHED_WT	0x3
 
-struct bus_type msm_iommu_sec_bus_type = {
-	.name = "msm_iommu_sec_bus",
-};
-
 static int msm_iommu_unmap_range(struct iommu_domain *domain, unsigned int va,
 				 unsigned int len);
 
@@ -224,7 +220,6 @@
 	.iommu_lock_acquire = _iommu_lock_acquire,
 	.iommu_lock_release = _iommu_lock_release,
 };
-EXPORT_SYMBOL(iommu_access_ops_v0);
 
 static int __flush_iotlb_va(struct iommu_domain *domain, unsigned int va)
 {
diff --git a/drivers/iommu/msm_iommu-v1.c b/drivers/iommu/msm_iommu-v1.c
index 7c57b67..06c6d94 100644
--- a/drivers/iommu/msm_iommu-v1.c
+++ b/drivers/iommu/msm_iommu-v1.c
@@ -141,7 +141,6 @@
 	.iommu_lock_acquire = _iommu_lock_acquire,
 	.iommu_lock_release = _iommu_lock_release,
 };
-EXPORT_SYMBOL(iommu_access_ops_v1);
 
 void iommu_halt(const struct msm_iommu_drvdata *iommu_drvdata)
 {
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
new file mode 100644
index 0000000..ebecd11
--- /dev/null
+++ b/drivers/iommu/msm_iommu.c
@@ -0,0 +1,97 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/export.h>
+#include <linux/iommu.h>
+#include <mach/iommu.h>
+
+static DEFINE_MUTEX(iommu_list_lock);
+static LIST_HEAD(iommu_list);
+
+static struct iommu_access_ops *iommu_access_ops;
+
+struct bus_type msm_iommu_sec_bus_type = {
+	.name = "msm_iommu_sec_bus",
+};
+
+void msm_set_iommu_access_ops(struct iommu_access_ops *ops)
+{
+	iommu_access_ops = ops;
+}
+
+struct iommu_access_ops *msm_get_iommu_access_ops()
+{
+	BUG_ON(iommu_access_ops == NULL);
+	return iommu_access_ops;
+}
+EXPORT_SYMBOL(msm_get_iommu_access_ops);
+
+void msm_iommu_add_drv(struct msm_iommu_drvdata *drv)
+{
+	mutex_lock(&iommu_list_lock);
+	list_add(&drv->list, &iommu_list);
+	mutex_unlock(&iommu_list_lock);
+}
+
+void msm_iommu_remove_drv(struct msm_iommu_drvdata *drv)
+{
+	mutex_lock(&iommu_list_lock);
+	list_del(&drv->list);
+	mutex_unlock(&iommu_list_lock);
+}
+
+static int find_iommu_ctx(struct device *dev, void *data)
+{
+	struct msm_iommu_ctx_drvdata *c;
+
+	c = dev_get_drvdata(dev);
+	if (!c || !c->name)
+		return 0;
+
+	return !strcmp(data, c->name);
+}
+
+static struct device *find_context(struct device *dev, const char *name)
+{
+	return device_find_child(dev, (void *)name, find_iommu_ctx);
+}
+
+struct device *msm_iommu_get_ctx(const char *ctx_name)
+{
+	struct msm_iommu_drvdata *drv;
+	struct device *dev = NULL;
+
+	mutex_lock(&iommu_list_lock);
+	list_for_each_entry(drv, &iommu_list, list) {
+		dev = find_context(drv->dev, ctx_name);
+		if (dev)
+			break;
+	}
+	mutex_unlock(&iommu_list_lock);
+
+	put_device(dev);
+
+	if (!dev || !dev_get_drvdata(dev)) {
+		pr_debug("Could not find context <%s>\n", ctx_name);
+		dev = ERR_PTR(-EPROBE_DEFER);
+	}
+
+	return dev;
+}
+EXPORT_SYMBOL(msm_iommu_get_ctx);
+
diff --git a/drivers/iommu/msm_iommu_dev-v0.c b/drivers/iommu/msm_iommu_dev-v0.c
index 4ee65d8..2d0fba2 100644
--- a/drivers/iommu/msm_iommu_dev-v0.c
+++ b/drivers/iommu/msm_iommu_dev-v0.c
@@ -32,64 +32,8 @@
 #include <mach/iommu.h>
 #include <mach/msm_bus.h>
 
-static DEFINE_MUTEX(iommu_list_lock);
-static LIST_HEAD(iommu_list);
-
 static struct of_device_id msm_iommu_v0_ctx_match_table[];
-
-void msm_iommu_add_drv(struct msm_iommu_drvdata *drv)
-{
-	mutex_lock(&iommu_list_lock);
-	list_add(&drv->list, &iommu_list);
-	mutex_unlock(&iommu_list_lock);
-}
-
-void msm_iommu_remove_drv(struct msm_iommu_drvdata *drv)
-{
-	mutex_lock(&iommu_list_lock);
-	list_del(&drv->list);
-	mutex_unlock(&iommu_list_lock);
-}
-
-static int find_iommu_ctx(struct device *dev, void *data)
-{
-	struct msm_iommu_ctx_drvdata *c;
-
-	c = dev_get_drvdata(dev);
-	if (!c || !c->name)
-		return 0;
-
-	return !strcmp(data, c->name);
-}
-
-static struct device *find_context(struct device *dev, const char *name)
-{
-	return device_find_child(dev, (void *)name, find_iommu_ctx);
-}
-
-struct device *msm_iommu_get_ctx(const char *ctx_name)
-{
-	struct msm_iommu_drvdata *drv;
-	struct device *dev = NULL;
-
-	mutex_lock(&iommu_list_lock);
-	list_for_each_entry(drv, &iommu_list, list) {
-		dev = find_context(drv->dev, ctx_name);
-		if (dev)
-			break;
-	}
-	mutex_unlock(&iommu_list_lock);
-
-	put_device(dev);
-
-	if (!dev || !dev_get_drvdata(dev)) {
-		pr_debug("Could not find context <%s>\n", ctx_name);
-		dev = ERR_PTR(-EPROBE_DEFER);
-	}
-
-	return dev;
-}
-EXPORT_SYMBOL(msm_iommu_get_ctx);
+static struct iommu_access_ops *msm_iommu_access_ops;
 
 static void msm_iommu_reset(void __iomem *base, void __iomem *glb_base, int ncb)
 {
@@ -454,7 +398,7 @@
 
 	drvdata->dev = &pdev->dev;
 
-	iommu_access_ops_v0.iommu_clk_on(drvdata);
+	msm_iommu_access_ops->iommu_clk_on(drvdata);
 
 	msm_iommu_reset(drvdata->base, drvdata->glb_base, drvdata->ncb);
 
@@ -462,7 +406,7 @@
 	if (ret)
 		goto fail_clk;
 
-	iommu_access_ops_v0.iommu_clk_off(drvdata);
+	msm_iommu_access_ops->iommu_clk_off(drvdata);
 
 	pr_info("device %s mapped at %p, with %d ctx banks\n",
 		drvdata->name, drvdata->base, drvdata->ncb);
@@ -478,7 +422,7 @@
 			pr_info("%s: pmon not available.\n", drvdata->name);
 		} else {
 			pmon_info->iommu.base = drvdata->base;
-			pmon_info->iommu.ops = &iommu_access_ops_v0;
+			pmon_info->iommu.ops = msm_iommu_access_ops;
 			pmon_info->iommu.hw_ops = iommu_pm_get_hw_ops_v0();
 			pmon_info->iommu.iommu_name = drvdata->name;
 			pmon_info->iommu.always_on = 1;
@@ -497,7 +441,7 @@
 	return 0;
 
 fail_clk:
-	iommu_access_ops_v0.iommu_clk_off(drvdata);
+	msm_iommu_access_ops->iommu_clk_off(drvdata);
 fail:
 	__put_bus_vote_client(drvdata);
 fail_mem:
@@ -697,9 +641,9 @@
 		goto fail;
 	}
 
-	iommu_access_ops_v0.iommu_clk_on(drvdata);
+	msm_iommu_access_ops->iommu_clk_on(drvdata);
 	__program_m2v_tables(drvdata, ctx_drvdata);
-	iommu_access_ops_v0.iommu_clk_off(drvdata);
+	msm_iommu_access_ops->iommu_clk_off(drvdata);
 
 	dev_info(&pdev->dev, "context %s using bank %d\n", ctx_drvdata->name,
 							   ctx_drvdata->num);
@@ -746,6 +690,11 @@
 static int __init msm_iommu_driver_init(void)
 {
 	int ret;
+
+	if (msm_soc_version_supports_iommu_v0()) {
+		msm_set_iommu_access_ops(&iommu_access_ops_v0);
+		msm_iommu_access_ops = msm_get_iommu_access_ops();
+	}
 	ret = platform_driver_register(&msm_iommu_driver);
 	if (ret != 0) {
 		pr_err("Failed to register IOMMU driver\n");
diff --git a/drivers/iommu/msm_iommu_dev-v1.c b/drivers/iommu/msm_iommu_dev-v1.c
index 11f43ae..bcd78a9 100644
--- a/drivers/iommu/msm_iommu_dev-v1.c
+++ b/drivers/iommu/msm_iommu_dev-v1.c
@@ -312,8 +312,6 @@
 
 	platform_set_drvdata(pdev, drvdata);
 
-	msm_iommu_sec_set_access_ops(&iommu_access_ops_v1);
-
 	pmon_info = msm_iommu_pm_alloc(&pdev->dev);
 	if (pmon_info != NULL) {
 		ret = msm_iommu_pmon_parse_dt(pdev, pmon_info);
@@ -322,7 +320,7 @@
 			pr_info("%s: pmon not available.\n", drvdata->name);
 		} else {
 			pmon_info->iommu.base = drvdata->base;
-			pmon_info->iommu.ops = &iommu_access_ops_v1;
+			pmon_info->iommu.ops = msm_get_iommu_access_ops();
 			pmon_info->iommu.hw_ops = iommu_pm_get_hw_ops_v1();
 			pmon_info->iommu.iommu_name = drvdata->name;
 			ret = msm_iommu_pm_iommu_register(pmon_info);
@@ -501,6 +499,10 @@
 {
 	int ret;
 
+	if (!msm_soc_version_supports_iommu_v0()) {
+		msm_set_iommu_access_ops(&iommu_access_ops_v1);
+		msm_iommu_sec_set_access_ops(&iommu_access_ops_v1);
+	}
 	ret = platform_driver_register(&msm_iommu_driver);
 	if (ret != 0) {
 		pr_err("Failed to register IOMMU driver\n");