summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErin Yan <xinyey@codeaurora.org>2018-08-09 10:21:31 +0800
committerGerrit - the friendly Code Review server <code-review@localhost>2018-08-14 19:49:31 -0700
commit2a7de566830b19f3e3e22506f9c0cd936758ac0d (patch)
tree306d71b5e187b6d3078702c84f66c4ceaddf6333
parent2d6cc4c81b1cb69379102c57a9a927c9583ccb8b (diff)
q6asm: retry asm_open_read and asm_open_loopback when session id conflict
The ADSP asm session ids are managed by the kernel driver. It's all right for native use cases. But for virtualization use cases, there's no way to synchronize the session ids' status among virtual machines. Playing back in one virtual machine is probably failed, because the session id may had been occupied by a use case in another virtual machine. The patch allowed audio capture stream and loopback stream to try all available session ids in case of session id conflict error, to support concurrent playback from multiple virtual machines. Change-Id: I01b4da65f3e5716dd14c20c614b53f3c45dd9ea3 Signed-off-by: Erin Yan <xinyey@codeaurora.org>
-rw-r--r--include/sound/q6asm-v2.h6
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c8
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c8
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c68
4 files changed, 80 insertions, 10 deletions
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index 3523fac586ce..8af49bb6a9fa 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -292,6 +292,9 @@ int q6asm_open_read_v4(struct audio_client *ac, uint32_t format,
int q6asm_open_read_v5(struct audio_client *ac, uint32_t format,
uint16_t bits_per_sample, bool ts_mode);
+int q6asm_open_read_with_retry(struct audio_client *ac, uint32_t format,
+ uint16_t bits_per_sample, bool ts_mode);
+
int q6asm_open_write(struct audio_client *ac, uint32_t format
/*, uint16_t bits_per_sample*/);
@@ -340,6 +343,9 @@ int q6asm_open_read_write_v2(struct audio_client *ac, uint32_t rd_format,
int q6asm_open_loopback_v2(struct audio_client *ac,
uint16_t bits_per_sample);
+int q6asm_open_loopback_with_retry(struct audio_client *ac,
+ uint16_t bits_per_sample);
+
int q6asm_open_transcode_loopback(struct audio_client *ac,
uint16_t bits_per_sample, uint32_t source_format,
uint32_t sink_format);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
index 9420534d3c5f..4f3f1d25b4a9 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
@@ -289,10 +289,12 @@ static int msm_pcm_open(struct snd_pcm_substream *substream)
mutex_unlock(&pcm->lock);
return -ENOMEM;
}
- pcm->session_id = pcm->audio_client->session;
+
pcm->audio_client->perf_mode = pdata->perf_mode;
- ret = q6asm_open_loopback_v2(pcm->audio_client,
- bits_per_sample);
+ ret = q6asm_open_loopback_with_retry(pcm->audio_client,
+ bits_per_sample);
+ pcm->session_id = pcm->audio_client->session;
+
if (ret < 0) {
dev_err(rtd->platform->dev,
"%s: pcm out open failed\n", __func__);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index 1e69ddcc3464..6798b50e682f 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -498,13 +498,7 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
__func__, params_channels(params),
prtd->audio_client->perf_mode);
- if (q6asm_get_svc_version(APR_SVC_ASM) >=
- ADSP_ASM_API_VERSION_V2)
- ret = q6asm_open_read_v5(prtd->audio_client,
- FORMAT_LINEAR_PCM,
- bits_per_sample, false);
- else
- ret = q6asm_open_read_v4(prtd->audio_client,
+ ret = q6asm_open_read_with_retry(prtd->audio_client,
FORMAT_LINEAR_PCM,
bits_per_sample, false);
if (ret < 0) {
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 0ad15e90bfc6..2f048fddcb08 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -2974,6 +2974,52 @@ int q6asm_open_read_v5(struct audio_client *ac, uint32_t format,
}
EXPORT_SYMBOL(q6asm_open_read_v5);
+static int q6asm_open_read_version_adaptor(struct audio_client *ac,
+ uint32_t format, uint16_t bits_per_sample, bool ts_mode)
+{
+ if (q6asm_get_svc_version(APR_SVC_ASM) >= ADSP_ASM_API_VERSION_V2)
+ return q6asm_open_read_v5(ac, FORMAT_LINEAR_PCM,
+ bits_per_sample, false);
+ else
+ return q6asm_open_read_v4(ac, FORMAT_LINEAR_PCM,
+ bits_per_sample, false);
+}
+
+/*
+ * q6asm_open_read_with_retry - Opens audio capture session, with retrying
+ * in case of session ID conflict
+ *
+ * @ac: Client session handle
+ * @format: encoder format
+ * @bits_per_sample: bit width of capture session
+ * @ts_mode: timestamp mode
+ */
+int q6asm_open_read_with_retry(struct audio_client *ac, uint32_t format,
+ uint16_t bits_per_sample, bool ts_mode)
+{
+ int i, rc;
+
+ mutex_lock(&session_lock);
+ for (i = 0; i < ASM_ACTIVE_STREAMS_ALLOWED; i++) {
+ rc = q6asm_open_read_version_adaptor(ac, format,
+ bits_per_sample, ts_mode);
+ if (rc != -EALREADY)
+ break;
+
+ pr_debug("%s: session %d is occupied, try next\n",
+ __func__, ac->session);
+ q6asm_session_set_ignore(ac->session);
+ rc = q6asm_session_try_next(ac);
+ if (rc < 0)
+ break;
+ }
+ q6asm_session_clean_ignore();
+ mutex_unlock(&session_lock);
+
+ return rc;
+}
+EXPORT_SYMBOL(q6asm_open_read_with_retry);
+
int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format,
uint32_t passthrough_flag)
{
@@ -3667,7 +3713,29 @@ int q6asm_open_loopback_v2(struct audio_client *ac, uint16_t bits_per_sample)
fail_cmd:
return rc;
}
+int q6asm_open_loopback_with_retry(struct audio_client *ac,
+ uint16_t bits_per_sample)
+{
+ int i, rc;
+
+ mutex_lock(&session_lock);
+ for (i = 0; i < ASM_ACTIVE_STREAMS_ALLOWED; i++) {
+ rc = q6asm_open_loopback_v2(ac, bits_per_sample);
+ if (rc != -EALREADY)
+ break;
+ pr_debug("%s: session %d is occupied, try next\n",
+ __func__, ac->session);
+ q6asm_session_set_ignore(ac->session);
+ rc = q6asm_session_try_next(ac);
+ if (rc < 0)
+ break;
+ }
+ q6asm_session_clean_ignore();
+ mutex_unlock(&session_lock);
+ return rc;
+}
+EXPORT_SYMBOL(q6asm_open_loopback_with_retry);
int q6asm_open_transcode_loopback(struct audio_client *ac,
uint16_t bits_per_sample,