ASoC: msm8960: Avoid the mutex access from event handler
Because q6asm_write use mutex to protect the shared data, this API
should not be called from event handler. Instead, calling
q6asm_write_nolock interface.
CRs-fixed: 298006
Signed-off-by: Jay Wang <jaywang@codeaurora.org>
diff --git a/include/sound/q6asm.h b/include/sound/q6asm.h
index 9c76942..e3507ee 100644
--- a/include/sound/q6asm.h
+++ b/include/sound/q6asm.h
@@ -186,6 +186,9 @@
void *q6asm_is_cpu_buf_avail(int dir, struct audio_client *ac,
uint32_t *size, uint32_t *idx);
+void *q6asm_is_cpu_buf_avail_nolock(int dir, struct audio_client *ac,
+ uint32_t *size, uint32_t *idx);
+
int q6asm_is_dsp_buf_avail(int dir, struct audio_client *ac);
/* File format specific configurations to be added below */
diff --git a/sound/soc/msm/msm-pcm-q6.c b/sound/soc/msm/msm-pcm-q6.c
index 5ae11dd..1826a57 100644
--- a/sound/soc/msm/msm-pcm-q6.c
+++ b/sound/soc/msm/msm-pcm-q6.c
@@ -96,12 +96,12 @@
break;
if (!prtd->mmap_flag)
break;
- if (q6asm_is_cpu_buf_avail(IN,
+ if (q6asm_is_cpu_buf_avail_nolock(IN,
prtd->audio_client,
&size, &idx)) {
pr_debug("%s:writing %d bytes of buffer to dsp 2\n",
__func__, prtd->pcm_count);
- q6asm_write(prtd->audio_client,
+ q6asm_write_nolock(prtd->audio_client,
prtd->pcm_count, 0, 0, NO_TIMESTAMP);
}
break;
@@ -126,27 +126,26 @@
atomic_inc(&prtd->in_count);
wake_up(&the_locks.read_wait);
if (prtd->mmap_flag
- && q6asm_is_cpu_buf_avail(OUT,
+ && q6asm_is_cpu_buf_avail_nolock(OUT,
prtd->audio_client,
&size, &idx))
- q6asm_read(prtd->audio_client);
+ q6asm_read_nolock(prtd->audio_client);
break;
}
case APR_BASIC_RSP_RESULT: {
- if (!prtd->mmap_flag
- && !atomic_read(&prtd->out_needed))
- break;
switch (payload[0]) {
case ASM_SESSION_CMD_RUN:
if (substream->stream
- != SNDRV_PCM_STREAM_PLAYBACK)
+ != SNDRV_PCM_STREAM_PLAYBACK) {
+ atomic_set(&prtd->start, 1);
break;
+ }
if (prtd->mmap_flag) {
pr_debug("%s:writing %d bytes"
" of buffer to dsp\n",
__func__,
prtd->pcm_count);
- q6asm_write(prtd->audio_client,
+ q6asm_write_nolock(prtd->audio_client,
prtd->pcm_count,
0, 0, NO_TIMESTAMP);
} else {
@@ -155,13 +154,14 @@
" of buffer to dsp\n",
__func__,
prtd->pcm_count);
- q6asm_write(prtd->audio_client,
+ q6asm_write_nolock(prtd->audio_client,
prtd->pcm_count,
0, 0, NO_TIMESTAMP);
atomic_dec(&prtd->out_needed);
wake_up(&the_locks.write_wait);
};
}
+ atomic_set(&prtd->start, 1);
break;
default:
break;
@@ -249,7 +249,6 @@
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
pr_debug("%s: Trigger start\n", __func__);
q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
- atomic_set(&prtd->start, 1);
break;
case SNDRV_PCM_TRIGGER_STOP:
pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 981f252..fddf34f 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -919,6 +919,52 @@
return NULL;
}
+void *q6asm_is_cpu_buf_avail_nolock(int dir, struct audio_client *ac,
+ uint32_t *size, uint32_t *index)
+{
+ void *data;
+ unsigned char idx;
+ struct audio_port_data *port;
+
+ if (!ac || ((dir != IN) && (dir != OUT)))
+ return NULL;
+
+ port = &ac->port[dir];
+
+ idx = port->cpu_buf;
+ if (port->buf == NULL) {
+ pr_debug("%s:Buffer pointer null\n", __func__);
+ return NULL;
+ }
+ /*
+ * dir 0: used = 0 means buf in use
+ * dir 1: used = 1 means buf in use
+ */
+ if (port->buf[idx].used == dir) {
+ /*
+ * To make it more robust, we could loop and get the
+ * next avail buf, its risky though
+ */
+ pr_debug("%s:Next buf idx[0x%x] not available,\
+ dir[%d]\n", __func__, idx, dir);
+ return NULL;
+ }
+ *size = port->buf[idx].actual_size;
+ *index = port->cpu_buf;
+ data = port->buf[idx].data;
+ pr_debug("%s:session[%d]index[%d] data[%p]size[%d]\n",
+ __func__, ac->session, port->cpu_buf,
+ data, *size);
+ /*
+ * By default increase the cpu_buf cnt
+ * user accesses this function,increase cpu
+ * buf(to avoid another api)
+ */
+ port->buf[idx].used = dir;
+ port->cpu_buf = ((port->cpu_buf + 1) & (port->max_buf_cnt - 1));
+ return data;
+}
+
int q6asm_is_dsp_buf_avail(int dir, struct audio_client *ac)
{
int ret = -1;