msm: bam_dmux: add power management only mode
Add an internal power management only mode for when the bam_dmux will
not be used as a data multiplexer, but solely for its A2 power collapse
feature support for other clients which may be interacting directly with
the A2.
CRs-Fixed: 372963
Change-Id: I75c8d3f5fa07318caa05c0c3ee5fe029b9874f13
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 c069761..3df566c 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -243,6 +243,7 @@
static DEFINE_MUTEX(smsm_cb_lock);
static DEFINE_MUTEX(delayed_ul_vote_lock);
static int need_delayed_ul_vote;
+static int power_management_only_mode;
struct outside_notify_func {
void (*notify)(void *, int, unsigned long);
@@ -1688,21 +1689,28 @@
in_global_reset = 0;
vote_dfab();
- i = sps_device_reset(a2_device_handle);
- if (i)
- pr_err("%s: device reset failed rc = %d\n", __func__, i);
- i = sps_connect(bam_tx_pipe, &tx_connection);
- if (i)
- pr_err("%s: tx connection failed rc = %d\n", __func__, i);
- i = sps_connect(bam_rx_pipe, &rx_connection);
- if (i)
- pr_err("%s: rx connection failed rc = %d\n", __func__, i);
- i = sps_register_event(bam_tx_pipe, &tx_register_event);
- if (i)
- pr_err("%s: tx event reg failed rc = %d\n", __func__, i);
- i = sps_register_event(bam_rx_pipe, &rx_register_event);
- if (i)
- pr_err("%s: rx event reg failed rc = %d\n", __func__, i);
+ if (!power_management_only_mode) {
+ i = sps_device_reset(a2_device_handle);
+ if (i)
+ pr_err("%s: device reset failed rc = %d\n", __func__,
+ i);
+ i = sps_connect(bam_tx_pipe, &tx_connection);
+ if (i)
+ pr_err("%s: tx connection failed rc = %d\n", __func__,
+ i);
+ i = sps_connect(bam_rx_pipe, &rx_connection);
+ if (i)
+ pr_err("%s: rx connection failed rc = %d\n", __func__,
+ i);
+ i = sps_register_event(bam_tx_pipe, &tx_register_event);
+ if (i)
+ pr_err("%s: tx event reg failed rc = %d\n", __func__,
+ i);
+ i = sps_register_event(bam_rx_pipe, &rx_register_event);
+ if (i)
+ pr_err("%s: rx event reg failed rc = %d\n", __func__,
+ i);
+ }
bam_connection_is_active = 1;
@@ -1711,7 +1719,8 @@
toggle_apps_ack();
complete_all(&bam_connection_completion);
- queue_rx();
+ if (!power_management_only_mode)
+ queue_rx();
}
static void disconnect_to_bam(void)
@@ -1733,11 +1742,13 @@
/* tear down BAM connection */
INIT_COMPLETION(bam_connection_completion);
- sps_disconnect(bam_tx_pipe);
- sps_disconnect(bam_rx_pipe);
+ if (!power_management_only_mode) {
+ sps_disconnect(bam_tx_pipe);
+ sps_disconnect(bam_rx_pipe);
+ __memzero(rx_desc_mem_buf.base, rx_desc_mem_buf.size);
+ __memzero(tx_desc_mem_buf.base, tx_desc_mem_buf.size);
+ }
unvote_dfab();
- __memzero(rx_desc_mem_buf.base, rx_desc_mem_buf.size);
- __memzero(tx_desc_mem_buf.base, tx_desc_mem_buf.size);
mutex_lock(&bam_rx_pool_mutexlock);
while (!list_empty(&bam_rx_pool)) {
@@ -2081,7 +2092,6 @@
int ret;
void *a2_virt_addr;
- unvote_dfab();
/* init BAM */
a2_virt_addr = ioremap_nocache(A2_PHYS_BASE, A2_PHYS_SIZE);
if (!a2_virt_addr) {
@@ -2114,6 +2124,10 @@
mutex_unlock(&delayed_ul_vote_lock);
toggle_apps_ack();
+ power_management_only_mode = 1;
+ bam_connection_is_active = 1;
+ complete_all(&bam_connection_completion);
+
return 0;
register_bam_failed: