msm: bam_dmux: add device tree support

Add support in the bam_dmux driver to receive the BAM hardware description
data from device tree.

Change-Id: Iee07bd647408d92b200908b46aab2fbdec3a085b
Signed-off-by: Jeffrey Hugo <jhugo@codeaurora.org>
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 125094d..fbc3e25 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -27,6 +27,7 @@
 #include <linux/clk.h>
 #include <linux/wakelock.h>
 #include <linux/kfifo.h>
+#include <linux/of.h>
 
 #include <mach/sps.h>
 #include <mach/bam_dmux.h>
@@ -175,6 +176,14 @@
 #define A2_PHYS_SIZE		0x2000
 #define BUFFER_SIZE		2048
 #define NUM_BUFFERS		32
+
+#ifndef A2_BAM_IRQ
+#define A2_BAM_IRQ -1
+#endif
+
+static void *a2_phys_base;
+static uint32_t a2_phys_size;
+static int a2_bam_irq;
 static struct sps_bam_props a2_props;
 static u32 a2_device_handle;
 static struct sps_pipe *bam_tx_pipe;
@@ -2028,16 +2037,17 @@
 
 	vote_dfab();
 	/* init BAM */
-	a2_virt_addr = ioremap_nocache(A2_PHYS_BASE, A2_PHYS_SIZE);
+	a2_virt_addr = ioremap_nocache((unsigned long)(a2_phys_base),
+							a2_phys_size);
 	if (!a2_virt_addr) {
 		pr_err("%s: ioremap failed\n", __func__);
 		ret = -ENOMEM;
 		goto ioremap_failed;
 	}
-	a2_props.phys_addr = A2_PHYS_BASE;
+	a2_props.phys_addr = (u32)(a2_phys_base);
 	a2_props.virt_addr = a2_virt_addr;
-	a2_props.virt_size = A2_PHYS_SIZE;
-	a2_props.irq = A2_BAM_IRQ;
+	a2_props.virt_size = a2_phys_size;
+	a2_props.irq = a2_bam_irq;
 	a2_props.options = SPS_BAM_OPT_IRQ_WAKEUP;
 	a2_props.num_pipes = A2_NUM_PIPES;
 	a2_props.summing_threshold = A2_SUMMING_THRESHOLD;
@@ -2199,16 +2209,17 @@
 	void *a2_virt_addr;
 
 	/* init BAM */
-	a2_virt_addr = ioremap_nocache(A2_PHYS_BASE, A2_PHYS_SIZE);
+	a2_virt_addr = ioremap_nocache((unsigned long)(a2_phys_base),
+							a2_phys_size);
 	if (!a2_virt_addr) {
 		pr_err("%s: ioremap failed\n", __func__);
 		ret = -ENOMEM;
 		goto ioremap_failed;
 	}
-	a2_props.phys_addr = A2_PHYS_BASE;
+	a2_props.phys_addr = (u32)(a2_phys_base);
 	a2_props.virt_addr = a2_virt_addr;
-	a2_props.virt_size = A2_PHYS_SIZE;
-	a2_props.irq = A2_BAM_IRQ;
+	a2_props.virt_size = a2_phys_size;
+	a2_props.irq = a2_bam_irq;
 	a2_props.options = SPS_BAM_OPT_IRQ_WAKEUP;
 	a2_props.num_pipes = A2_NUM_PIPES;
 	a2_props.summing_threshold = A2_SUMMING_THRESHOLD;
@@ -2321,11 +2332,35 @@
 static int bam_dmux_probe(struct platform_device *pdev)
 {
 	int rc;
+	struct resource *r;
 
 	DBG("%s probe called\n", __func__);
 	if (bam_mux_initialized)
 		return 0;
 
+	if (pdev->dev.of_node) {
+		r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		if (!r) {
+			pr_err("%s: reg field missing\n", __func__);
+			return -ENODEV;
+		}
+		a2_phys_base = (void *)(r->start);
+		a2_phys_size = (uint32_t)(resource_size(r));
+		a2_bam_irq = platform_get_irq(pdev, 0);
+		if (a2_bam_irq == -ENXIO) {
+			pr_err("%s: irq field missing\n", __func__);
+			return -ENODEV;
+		}
+		DBG("%s: base:%p size:%x irq:%d\n", __func__,
+							a2_phys_base,
+							a2_phys_size,
+							a2_bam_irq);
+	} else { /* fallback to default init data */
+		a2_phys_base = (void *)(A2_PHYS_BASE);
+		a2_phys_size = A2_PHYS_SIZE;
+		a2_bam_irq = A2_BAM_IRQ;
+	}
+
 	xo_clk = clk_get(&pdev->dev, "xo");
 	if (IS_ERR(xo_clk)) {
 		bam_dmux_log("%s: did not get xo clock\n", __func__);
@@ -2409,11 +2444,17 @@
 	return 0;
 }
 
+static struct of_device_id msm_match_table[] = {
+	{.compatible = "qcom,bam_dmux"},
+	{},
+};
+
 static struct platform_driver bam_dmux_driver = {
 	.probe		= bam_dmux_probe,
 	.driver		= {
 		.name	= "BAM_RMNT",
 		.owner	= THIS_MODULE,
+		.of_match_table = msm_match_table,
 	},
 };