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,
},
};