qdsp5: audio: Add support for adsp dump mechanism
Whenever timeout happens at apps while waiting for response
from ADSP services, dsp or audmgr apps initiates command to
collect cache coherent dumps to modem ADSP services to collect
dump. This will help in debugging the timeout issue.
Change-Id: Ic48d2815611afea8fed38c2c235e539619bed0ea
Signed-off-by: Chaithanya Krishna Bacharaju <chaithan@codeaurora.org>
diff --git a/arch/arm/mach-msm/include/mach/msm_adsp.h b/arch/arm/mach-msm/include/mach/msm_adsp.h
index e40c07d..ea08f0c 100644
--- a/arch/arm/mach-msm/include/mach/msm_adsp.h
+++ b/arch/arm/mach-msm/include/mach/msm_adsp.h
@@ -39,6 +39,7 @@
void msm_adsp_put(struct msm_adsp_module *module);
int msm_adsp_enable(struct msm_adsp_module *module);
int msm_adsp_disable(struct msm_adsp_module *module);
+int msm_adsp_dump(struct msm_adsp_module *module);
int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate);
int msm_adsp_disable_event_rsp(struct msm_adsp_module *module);
int32_t get_adsp_resource(unsigned short client_idx,
diff --git a/arch/arm/mach-msm/qdsp5/adsp.c b/arch/arm/mach-msm/qdsp5/adsp.c
index 6189da8..81af66b 100644
--- a/arch/arm/mach-msm/qdsp5/adsp.c
+++ b/arch/arm/mach-msm/qdsp5/adsp.c
@@ -1080,6 +1080,21 @@
return 0;
}
+int msm_adsp_dump(struct msm_adsp_module *module)
+{
+ int rc = 0;
+ if (!module) {
+ MM_INFO("Invalid module. Dumps are not collected\n");
+ return -EINVAL;
+ }
+ MM_INFO("starting DSP DUMP\n");
+ rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_CORE_DUMP,
+ module->id, module);
+ MM_INFO("DSP DUMP done rc =%d\n", rc);
+ return rc;
+}
+EXPORT_SYMBOL(msm_adsp_dump);
+
int msm_adsp_enable(struct msm_adsp_module *module)
{
int rc = 0;
@@ -1123,6 +1138,7 @@
rc = 0;
} else {
MM_ERR("module '%s' enable timed out\n", module->name);
+ msm_adsp_dump(module);
rc = -ETIMEDOUT;
}
if (module->open_count++ == 0 && module->clk)
diff --git a/arch/arm/mach-msm/qdsp5/adsp.h b/arch/arm/mach-msm/qdsp5/adsp.h
index 50f5b83..4e9d311 100644
--- a/arch/arm/mach-msm/qdsp5/adsp.h
+++ b/arch/arm/mach-msm/qdsp5/adsp.h
@@ -152,6 +152,7 @@
RPC_ADSP_RTOS_CMD_SET_STATE,
RPC_ADSP_RTOS_CMD_REMOTE_INIT_INFO_EVENT,
RPC_ADSP_RTOS_CMD_GET_INIT_INFO,
+ RPC_ADSP_RTOS_CMD_CORE_DUMP,
};
enum rpc_adsp_rtos_mod_status_type {
diff --git a/arch/arm/mach-msm/qdsp5/audio_aac.c b/arch/arm/mach-msm/qdsp5/audio_aac.c
index 46a80d7..c36cac7 100644
--- a/arch/arm/mach-msm/qdsp5/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp5/audio_aac.c
@@ -261,8 +261,10 @@
cfg.snd_method = RPC_SND_METHOD_MIDI;
rc = audmgr_enable(&audio->audmgr, &cfg);
- if (rc < 0)
+ if (rc < 0) {
+ msm_adsp_dump(audio->audplay);
return rc;
+ }
}
if (msm_adsp_enable(audio->audplay)) {
@@ -306,8 +308,12 @@
wake_up(&audio->read_wait);
msm_adsp_disable(audio->audplay);
audpp_disable(audio->dec_id, audio);
- if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
- audmgr_disable(&audio->audmgr);
+ if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+ rc = audmgr_disable(&audio->audmgr);
+ if (rc < 0)
+ msm_adsp_dump(audio->audplay);
+ }
+
audio->out_needed = 0;
rmt_put_resource(audio);
audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_ac3.c b/arch/arm/mach-msm/qdsp5/audio_ac3.c
index e453ec5..b5337bd 100644
--- a/arch/arm/mach-msm/qdsp5/audio_ac3.c
+++ b/arch/arm/mach-msm/qdsp5/audio_ac3.c
@@ -252,8 +252,10 @@
cfg.snd_method = RPC_SND_METHOD_MIDI;
rc = audmgr_enable(&audio->audmgr, &cfg);
- if (rc < 0)
+ if (rc < 0) {
+ msm_adsp_dump(audio->audplay);
return rc;
+ }
}
if (msm_adsp_enable(audio->audplay)) {
@@ -296,8 +298,11 @@
wake_up(&audio->read_wait);
msm_adsp_disable(audio->audplay);
audpp_disable(audio->dec_id, audio);
- if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
- audmgr_disable(&audio->audmgr);
+ if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+ rc = audmgr_disable(&audio->audmgr);
+ if (rc < 0)
+ msm_adsp_dump(audio->audplay);
+ }
audio->out_needed = 0;
rmt_put_resource(audio);
audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrnb.c b/arch/arm/mach-msm/qdsp5/audio_amrnb.c
index 0792e3f..4aa7403 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrnb.c
@@ -265,8 +265,10 @@
cfg.snd_method = RPC_SND_METHOD_MIDI;
rc = audmgr_enable(&audio->audmgr, &cfg);
- if (rc < 0)
+ if (rc < 0) {
+ msm_adsp_dump(audio->audplay);
return rc;
+ }
}
if (msm_adsp_enable(audio->audplay)) {
@@ -310,8 +312,11 @@
wake_up(&audio->read_wait);
msm_adsp_disable(audio->audplay);
audpp_disable(audio->dec_id, audio);
- if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
- audmgr_disable(&audio->audmgr);
+ if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+ rc = audmgr_disable(&audio->audmgr);
+ if (rc < 0)
+ msm_adsp_dump(audio->audplay);
+ }
audio->out_needed = 0;
rmt_put_resource(audio);
audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrwb.c b/arch/arm/mach-msm/qdsp5/audio_amrwb.c
index 7d37cea..57df4ad 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrwb.c
@@ -262,8 +262,10 @@
cfg.snd_method = RPC_SND_METHOD_MIDI;
rc = audmgr_enable(&audio->audmgr, &cfg);
- if (rc < 0)
+ if (rc < 0) {
+ msm_adsp_dump(audio->audplay);
return rc;
+ }
}
if (msm_adsp_enable(audio->audplay)) {
@@ -307,8 +309,11 @@
wake_up(&audio->read_wait);
msm_adsp_disable(audio->audplay);
audpp_disable(audio->dec_id, audio);
- if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
- audmgr_disable(&audio->audmgr);
+ if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+ rc = audmgr_disable(&audio->audmgr);
+ if (rc < 0)
+ msm_adsp_dump(audio->audplay);
+ }
audio->out_needed = 0;
rmt_put_resource(audio);
audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_evrc.c b/arch/arm/mach-msm/qdsp5/audio_evrc.c
index 155b0e1..0799ee1 100644
--- a/arch/arm/mach-msm/qdsp5/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp5/audio_evrc.c
@@ -255,8 +255,10 @@
cfg.snd_method = RPC_SND_METHOD_MIDI;
rc = audmgr_enable(&audio->audmgr, &cfg);
- if (rc < 0)
+ if (rc < 0) {
+ msm_adsp_dump(audio->audplay);
return rc;
+ }
}
if (msm_adsp_enable(audio->audplay)) {
@@ -299,8 +301,11 @@
wake_up(&audio->read_wait);
msm_adsp_disable(audio->audplay);
audpp_disable(audio->dec_id, audio);
- if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
- audmgr_disable(&audio->audmgr);
+ if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+ rc = audmgr_disable(&audio->audmgr);
+ if (rc < 0)
+ msm_adsp_dump(audio->audplay);
+ }
audio->out_needed = 0;
rmt_put_resource(audio);
audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_lpa.c b/arch/arm/mach-msm/qdsp5/audio_lpa.c
index 8120d7b..e896e85 100644
--- a/arch/arm/mach-msm/qdsp5/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp5/audio_lpa.c
@@ -293,9 +293,10 @@
cfg.snd_method = RPC_SND_METHOD_MIDI;
rc = audmgr_enable(&audio->audmgr, &cfg);
- if (rc < 0)
+ if (rc < 0) {
+ msm_adsp_dump(audio->audplay);
return rc;
-
+ }
if (msm_adsp_enable(audio->audplay)) {
MM_ERR("msm_adsp_enable(audplay) failed\n");
audmgr_disable(&audio->audmgr);
@@ -335,7 +336,9 @@
wake_up(&audio->write_wait);
msm_adsp_disable(audio->audplay);
audpp_disable(audio->dec_id, audio);
- audmgr_disable(&audio->audmgr);
+ rc = audmgr_disable(&audio->audmgr);
+ if (rc < 0)
+ msm_adsp_dump(audio->audplay);
audio->out_needed = 0;
rmt_put_resource(audio);
audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_mp3.c b/arch/arm/mach-msm/qdsp5/audio_mp3.c
index b8c64be..a606bd5 100644
--- a/arch/arm/mach-msm/qdsp5/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp5/audio_mp3.c
@@ -330,8 +330,10 @@
cfg.snd_method = RPC_SND_METHOD_MIDI;
rc = audmgr_enable(&audio->audmgr, &cfg);
- if (rc < 0)
+ if (rc < 0) {
+ msm_adsp_dump(audio->audplay);
return rc;
+ }
}
if (msm_adsp_enable(audio->audplay)) {
@@ -376,8 +378,11 @@
wake_up(&audio->read_wait);
msm_adsp_disable(audio->audplay);
audpp_disable(audio->dec_id, audio);
- if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
- audmgr_disable(&audio->audmgr);
+ if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+ rc = audmgr_disable(&audio->audmgr);
+ if (rc < 0)
+ msm_adsp_dump(audio->audplay);
+ }
audio->out_needed = 0;
rmt_put_resource(audio);
audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm.c b/arch/arm/mach-msm/qdsp5/audio_pcm.c
index 3eb72c8..d19f80b 100644
--- a/arch/arm/mach-msm/qdsp5/audio_pcm.c
+++ b/arch/arm/mach-msm/qdsp5/audio_pcm.c
@@ -299,9 +299,10 @@
cfg.snd_method = RPC_SND_METHOD_MIDI;
rc = audmgr_enable(&audio->audmgr, &cfg);
- if (rc < 0)
+ if (rc < 0) {
+ msm_adsp_dump(audio->audplay);
return rc;
-
+ }
if (msm_adsp_enable(audio->audplay)) {
MM_ERR("msm_adsp_enable(audplay) failed\n");
audmgr_disable(&audio->audmgr);
@@ -341,7 +342,9 @@
wake_up(&audio->write_wait);
msm_adsp_disable(audio->audplay);
audpp_disable(audio->dec_id, audio);
- audmgr_disable(&audio->audmgr);
+ rc = audmgr_disable(&audio->audmgr);
+ if (rc < 0)
+ msm_adsp_dump(audio->audplay);
audio->out_needed = 0;
rmt_put_resource(audio);
audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
index 68ffcfef..7b2090d 100644
--- a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
@@ -218,9 +218,10 @@
cfg.snd_method = RPC_SND_METHOD_MIDI;
rc = audmgr_enable(&audio->audmgr, &cfg);
- if (rc < 0)
+ if (rc < 0) {
+ msm_adsp_dump(audio->audrec);
return rc;
-
+ }
if (audpreproc_enable(audio->enc_id, &audpre_dsp_event, audio)) {
MM_ERR("msm_adsp_enable(audpreproc) failed\n");
audmgr_disable(&audio->audmgr);
@@ -249,6 +250,8 @@
/* must be called with audio->lock held */
static int audpcm_in_disable(struct audio_in *audio)
{
+ int rc;
+
if (audio->enabled) {
audio->enabled = 0;
@@ -262,7 +265,9 @@
/*reset the sampling frequency information at audpreproc layer*/
audio->session_info.sampling_freq = 0;
audpreproc_update_audrec_info(&audio->session_info);
- audmgr_disable(&audio->audmgr);
+ rc = audmgr_disable(&audio->audmgr);
+ if (rc < 0)
+ msm_adsp_dump(audio->audrec);
}
return 0;
}
diff --git a/arch/arm/mach-msm/qdsp5/audio_qcelp.c b/arch/arm/mach-msm/qdsp5/audio_qcelp.c
index 876c909..3fc489c 100644
--- a/arch/arm/mach-msm/qdsp5/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp5/audio_qcelp.c
@@ -251,8 +251,10 @@
cfg.snd_method = RPC_SND_METHOD_MIDI;
rc = audmgr_enable(&audio->audmgr, &cfg);
- if (rc < 0)
+ if (rc < 0) {
+ msm_adsp_dump(audio->audplay);
return rc;
+ }
}
if (msm_adsp_enable(audio->audplay)) {
@@ -296,8 +298,11 @@
wake_up(&audio->read_wait);
msm_adsp_disable(audio->audplay);
audpp_disable(audio->dec_id, audio);
- if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
- audmgr_disable(&audio->audmgr);
+ if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+ rc = audmgr_disable(&audio->audmgr);
+ if (rc < 0)
+ msm_adsp_dump(audio->audplay);
+ }
audio->out_needed = 0;
rmt_put_resource(audio);
audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_wma.c b/arch/arm/mach-msm/qdsp5/audio_wma.c
index 6d520b4..f7d54cc 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wma.c
@@ -268,8 +268,10 @@
cfg.snd_method = RPC_SND_METHOD_MIDI;
rc = audmgr_enable(&audio->audmgr, &cfg);
- if (rc < 0)
+ if (rc < 0) {
+ msm_adsp_dump(audio->audplay);
return rc;
+ }
}
if (msm_adsp_enable(audio->audplay)) {
@@ -314,8 +316,11 @@
wake_up(&audio->read_wait);
msm_adsp_disable(audio->audplay);
audpp_disable(audio->dec_id, audio);
- if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
- audmgr_disable(&audio->audmgr);
+ if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+ rc = audmgr_disable(&audio->audmgr);
+ if (rc < 0)
+ msm_adsp_dump(audio->audplay);
+ }
audio->out_needed = 0;
rmt_put_resource(audio);
audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_wmapro.c b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
index a08f3c9..8dba4a6 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
@@ -266,8 +266,10 @@
cfg.snd_method = RPC_SND_METHOD_MIDI;
rc = audmgr_enable(&audio->audmgr, &cfg);
- if (rc < 0)
+ if (rc < 0) {
+ msm_adsp_dump(audio->audplay);
return rc;
+ }
if (msm_adsp_enable(audio->audplay)) {
MM_ERR("msm_adsp_enable(audplay) failed\n");
@@ -309,7 +311,10 @@
wake_up(&audio->read_wait);
msm_adsp_disable(audio->audplay);
audpp_disable(audio->dec_id, audio);
- audmgr_disable(&audio->audmgr);
+ rc = audmgr_disable(&audio->audmgr);
+ if (rc < 0)
+ msm_adsp_dump(audio->audplay);
+
audio->out_needed = 0;
rmt_put_resource(audio);
audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audpp.c b/arch/arm/mach-msm/qdsp5/audpp.c
index b4ead5c..b4b7338f 100644
--- a/arch/arm/mach-msm/qdsp5/audpp.c
+++ b/arch/arm/mach-msm/qdsp5/audpp.c
@@ -292,6 +292,7 @@
MM_INFO("ENABLE\n");
if (!audpp->enabled) {
audpp->enabled = 1;
+ wake_up(&audpp->event_wait);
audpp_broadcast(audpp, id, msg);
} else {
cid = msg[1];
@@ -344,6 +345,7 @@
struct audpp_state *audpp = &the_audpp_state;
uint16_t msg[8];
int res = 0;
+ int rc;
if (id < -1 || id > 4)
return -EINVAL;
@@ -374,6 +376,11 @@
LOG(EV_ENABLE, 2);
msm_adsp_enable(audpp->mod);
audpp_dsp_config(1);
+ rc = wait_event_timeout(audpp->event_wait,
+ (audpp->enabled == 1),
+ 3 * HZ);
+ if (rc == 0)
+ msm_adsp_dump(audpp->mod);
} else {
if (audpp->enabled) {
msg[0] = AUDPP_MSG_ENA_ENA;
@@ -424,13 +431,17 @@
MM_DBG("disable\n");
LOG(EV_DISABLE, 2);
audpp_dsp_config(0);
- rc = wait_event_interruptible(audpp->event_wait,
- (audpp->enabled == 0));
+ rc = wait_event_timeout(audpp->event_wait,
+ (audpp->enabled == 0),
+ 3 * HZ);
if (audpp->enabled == 0)
MM_INFO("Received CFG_MSG_DISABLE from ADSP\n");
- else
+ else {
MM_ERR("Didn't receive CFG_MSG DISABLE \
message from ADSP\n");
+ if (rc == 0)
+ msm_adsp_dump(audpp->mod);
+ }
msm_adsp_disable(audpp->mod);
msm_adsp_put(audpp->mod);
audpp->mod = NULL;