Merge "ASoC: msm: qdsp6v2: don't assume playback started"
diff --git a/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c
index 4297ddb..39e6934 100644
--- a/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c
@@ -141,7 +141,7 @@
}
case ASM_DATA_EVENT_RENDERED_EOS:
pr_debug("ASM_DATA_CMDRSP_EOS\n");
- prtd->cmd_ack = 1;
+ clear_bit(CMD_EOS, &prtd->cmd_pending);
wake_up(&the_locks.eos_wait);
break;
case ASM_DATA_EVENT_READ_DONE_V2: {
@@ -241,7 +241,7 @@
atomic_set(&prtd->out_count, runtime->periods);
prtd->enabled = 1;
- prtd->cmd_ack = 0;
+ prtd->cmd_pending = 0;
prtd->cmd_interrupt = 0;
return 0;
@@ -299,8 +299,12 @@
atomic_set(&prtd->start, 0);
if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
break;
- prtd->cmd_ack = 0;
+ /* pending CMD_EOS isn't expected */
+ WARN_ON_ONCE(test_bit(CMD_EOS, &prtd->cmd_pending));
+ set_bit(CMD_EOS, &prtd->cmd_pending);
q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
+ if (ret)
+ clear_bit(CMD_EOS, &prtd->cmd_pending);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
@@ -379,9 +383,6 @@
prtd->audio_client->perf_mode,
prtd->session_id, substream->stream);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- prtd->cmd_ack = 1;
-
ret = snd_pcm_hw_constraint_list(runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
&constraints_sample_rates);
@@ -502,13 +503,15 @@
int dir = 0;
int ret = 0;
- pr_debug("%s\n", __func__);
+ pr_debug("%s: cmd_pending 0x%lx\n", __func__, prtd->cmd_pending);
dir = IN;
ret = wait_event_timeout(the_locks.eos_wait,
- prtd->cmd_ack, 5 * HZ);
+ !test_bit(CMD_EOS, &prtd->cmd_pending),
+ 5 * HZ);
if (!ret)
- pr_err("%s: CMD_EOS failed\n", __func__);
+ pr_err("%s: CMD_EOS failed, cmd_pending 0x%lx\n",
+ __func__, prtd->cmd_pending);
q6asm_cmd(prtd->audio_client, CMD_CLOSE);
q6asm_audio_client_buf_free_contiguous(dir,
prtd->audio_client);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index 49bc488..11326f6 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -143,7 +143,7 @@
}
case ASM_DATA_EVENT_RENDERED_EOS:
pr_debug("ASM_DATA_EVENT_RENDERED_EOS\n");
- prtd->cmd_ack = 1;
+ clear_bit(CMD_EOS, &prtd->cmd_pending);
wake_up(&the_locks.eos_wait);
break;
case ASM_DATA_EVENT_READ_DONE_V2: {
@@ -243,7 +243,7 @@
atomic_set(&prtd->out_count, runtime->periods);
prtd->enabled = 1;
- prtd->cmd_ack = 0;
+ prtd->cmd_pending = 0;
prtd->cmd_interrupt = 0;
return 0;
@@ -312,8 +312,12 @@
atomic_set(&prtd->start, 0);
if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
break;
- prtd->cmd_ack = 0;
+ /* pending CMD_EOS isn't expected */
+ WARN_ON_ONCE(test_bit(CMD_EOS, &prtd->cmd_pending));
+ set_bit(CMD_EOS, &prtd->cmd_pending);
ret = q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
+ if (ret)
+ clear_bit(CMD_EOS, &prtd->cmd_pending);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
@@ -473,14 +477,16 @@
int dir = 0;
int ret = 0;
- pr_debug("%s\n", __func__);
+ pr_debug("%s: cmd_pending 0x%lx\n", __func__, prtd->cmd_pending);
if (prtd->audio_client) {
dir = IN;
ret = wait_event_timeout(the_locks.eos_wait,
- prtd->cmd_ack, 5 * HZ);
+ !test_bit(CMD_EOS, &prtd->cmd_pending),
+ 5 * HZ);
if (!ret)
- pr_err("%s: CMD_EOS failed\n", __func__);
+ pr_err("%s: CMD_EOS failed, cmd_pending 0x%lx\n",
+ __func__, prtd->cmd_pending);
q6asm_cmd(prtd->audio_client, CMD_CLOSE);
q6asm_audio_client_buf_free_contiguous(dir,
prtd->audio_client);
@@ -701,7 +707,6 @@
msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id,
prtd->audio_client->perf_mode,
prtd->session_id, substream->stream);
- prtd->cmd_ack = 1;
}
/* Capture Path */
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
index f7719ed..5d5c995 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
@@ -72,6 +72,13 @@
int enabled;
int close_ack;
int cmd_ack;
+ /*
+ * cmd_ack doesn't tell if paticular command has been sent so can't
+ * determine if it needs to wait for completion.
+ * Use cmd_pending instead when checking whether a command is been
+ * sent or not.
+ */
+ unsigned long cmd_pending;
atomic_t start;
atomic_t stop;
atomic_t out_count;