platform: msm_shared: Wait for apps-rpm channel to be populated
Appsl runs & initializes SMD driver before rpm populates the channel
entries in SMEM. Due to this appsbl fails to fidn the apps-rpm
communication channel & halts. To void this race condition wait in appsbl
for channel entry to be populated in SMEM by rpm.
Change-Id: I045d29fd08b5ffbf383a901352f6d5accccfbb2f
diff --git a/platform/msm_shared/smd.c b/platform/msm_shared/smd.c
index a076f65..54a0b5b 100644
--- a/platform/msm_shared/smd.c
+++ b/platform/msm_shared/smd.c
@@ -38,6 +38,8 @@
#include <malloc.h>
#include <bits.h>
+#define SMD_CHANNEL_ACCESS_RETRY 1000000
+
smd_channel_alloc_entry_t *smd_channel_alloc_entry;
static event_t smd_closed;
@@ -64,7 +66,7 @@
ch->port_info->ch0.state_updated = flag;
}
-void smd_get_channel_entry(smd_channel_info_t *ch, uint32_t ch_type)
+int smd_get_channel_entry(smd_channel_info_t *ch, uint32_t ch_type)
{
int i = 0;
@@ -77,12 +79,14 @@
}
}
- /* Channel not found */
+ /* Channel not found, retry again */
if(i == SMEM_NUM_SMD_STREAM_CHANNELS)
{
- dprintf(CRITICAL, "smd channel type %x not found\n", ch_type);
- ASSERT(0);
+ dprintf(SPEW, "Channel not found, wait and retry for the update\n");
+ return -1;
}
+
+ return 0;
}
int smd_get_channel_info(smd_channel_info_t *ch, uint32_t ch_type)
@@ -92,8 +96,10 @@
uint32_t fifo_buf_size = 0;
uint32_t size = 0;
- smd_get_channel_entry(ch, ch_type);
+ ret = smd_get_channel_entry(ch, ch_type);
+ if (ret)
+ return ret;
ch->port_info = smem_get_alloc_entry(SMEM_SMD_BASE_ID + ch->alloc_entry.cid,
&size);
@@ -112,20 +118,35 @@
int smd_init(smd_channel_info_t *ch, uint32_t ch_type)
{
unsigned ret = 0;
+ int chnl_found = 0;
+ uint64_t timeout = SMD_CHANNEL_ACCESS_RETRY;
smd_channel_alloc_entry = (smd_channel_alloc_entry_t*)memalign(CACHE_LINE, SMD_CHANNEL_ALLOC_MAX);
ASSERT(smd_channel_alloc_entry);
- ret = smem_read_alloc_entry(SMEM_CHANNEL_ALLOC_TBL,
- (void*)smd_channel_alloc_entry,
- SMD_CHANNEL_ALLOC_MAX);
- if(ret)
- {
- dprintf(CRITICAL,"ERROR reading smem channel alloc tbl\n");
- return -1;
- }
+ dprintf(INFO, "Waiting for the RPM to populate smd channel table\n");
- smd_get_channel_info(ch, ch_type);
+ do
+ {
+ ret = smem_read_alloc_entry(SMEM_CHANNEL_ALLOC_TBL,
+ (void*)smd_channel_alloc_entry,
+ SMD_CHANNEL_ALLOC_MAX);
+ if(ret)
+ {
+ dprintf(CRITICAL,"ERROR reading smem channel alloc tbl\n");
+ return -1;
+ }
+
+ chnl_found = smd_get_channel_info(ch, ch_type);
+ timeout--;
+ udelay(10);
+ } while(timeout && chnl_found);
+
+ if (!timeout)
+ {
+ dprintf(CRITICAL, "Apps timed out waiting for RPM-->APPS channel entry\n");
+ ASSERT(0);
+ }
register_int_handler(SMD_IRQ, smd_irq_handler, ch);