summaryrefslogtreecommitdiff
path: root/sound/soc/fsl/imx-pcm-rpmsg.c
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@freescale.com>2017-02-23 15:54:20 +0800
committerDong Aisheng <aisheng.dong@nxp.com>2019-11-25 15:52:52 +0800
commitc040763b306ba030c4213e9a927038e9e217b885 (patch)
tree79175a31fc6258b17f4d2924b7d77fadc39e0020 /sound/soc/fsl/imx-pcm-rpmsg.c
parent45aa9064e240a0174754aed88a0f9c6dd83fe1a4 (diff)
MLK-14254: ASoC: imx_pcm_rpmsg: fix cmd dropped by work queue
The test case is to playback a bitstream, then repeat ctrl+z and fg, several times later, the playback is failed to continue. The reason is if the work is pending in work queue, send second time of this work, the second work is dropped by work queue. so use one work for one cmd is not fit for audio case. use a work loop for audio cmd to fix this issue. Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
Diffstat (limited to 'sound/soc/fsl/imx-pcm-rpmsg.c')
-rw-r--r--sound/soc/fsl/imx-pcm-rpmsg.c65
1 files changed, 35 insertions, 30 deletions
diff --git a/sound/soc/fsl/imx-pcm-rpmsg.c b/sound/soc/fsl/imx-pcm-rpmsg.c
index ace3bd77c8c2..2ece2cfaa728 100644
--- a/sound/soc/fsl/imx-pcm-rpmsg.c
+++ b/sound/soc/fsl/imx-pcm-rpmsg.c
@@ -189,14 +189,13 @@ static int imx_rpmsg_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
struct i2s_rpmsg_s *rpmsg = &i2s_info->send_msg[substream->stream];
- u8 cmd;
+ u8 index = i2s_info->work_index;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- cmd = I2S_TX_BUFFER;
+ rpmsg->header.cmd = I2S_TX_BUFFER;
else
- cmd = I2S_RX_BUFFER;
+ rpmsg->header.cmd = I2S_RX_BUFFER;
- rpmsg->header.cmd = cmd;
rpmsg->param.buffer_addr = substream->runtime->dma_addr;
rpmsg->param.buffer_size = snd_pcm_lib_buffer_bytes(substream);
rpmsg->param.period_size = snd_pcm_lib_period_bytes(substream);
@@ -205,9 +204,11 @@ static int imx_rpmsg_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
i2s_info->num_period[substream->stream] =
rpmsg->param.buffer_size/rpmsg->param.period_size;
- memcpy(&i2s_info->work_list[cmd].msg, rpmsg,
+ memcpy(&i2s_info->work_list[index].msg, rpmsg,
sizeof(struct i2s_rpmsg_s));
- queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[cmd].work);
+ queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+ i2s_info->work_index++;
+ i2s_info->work_index %= WORK_MAX_NUM;
i2s_info->callback[substream->stream] = imx_rpmsg_pcm_dma_complete;
i2s_info->callback_param[substream->stream] = substream;
@@ -221,17 +222,18 @@ static void imx_rpmsg_async_issue_pending(struct snd_pcm_substream *substream)
struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
struct i2s_rpmsg_s *rpmsg = &i2s_info->send_msg[substream->stream];
- u8 cmd;
+ u8 index = i2s_info->work_index;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- cmd = I2S_TX_START;
+ rpmsg->header.cmd = I2S_TX_START;
else
- cmd = I2S_RX_START;
+ rpmsg->header.cmd = I2S_RX_START;
- rpmsg->header.cmd = cmd;
- memcpy(&i2s_info->work_list[cmd].msg, rpmsg,
+ memcpy(&i2s_info->work_list[index].msg, rpmsg,
sizeof(struct i2s_rpmsg_s));
- queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[cmd].work);
+ queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+ i2s_info->work_index++;
+ i2s_info->work_index %= WORK_MAX_NUM;
}
static int imx_rpmsg_resume(struct snd_pcm_substream *substream)
@@ -241,17 +243,18 @@ static int imx_rpmsg_resume(struct snd_pcm_substream *substream)
struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
struct i2s_rpmsg_s *rpmsg = &i2s_info->send_msg[substream->stream];
- u8 cmd;
+ u8 index = i2s_info->work_index;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- cmd = I2S_TX_RESTART;
+ rpmsg->header.cmd = I2S_TX_RESTART;
else
- cmd = I2S_RX_RESTART;
+ rpmsg->header.cmd = I2S_RX_RESTART;
- rpmsg->header.cmd = cmd;
- memcpy(&i2s_info->work_list[cmd].msg, rpmsg,
+ memcpy(&i2s_info->work_list[index].msg, rpmsg,
sizeof(struct i2s_rpmsg_s));
- queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[cmd].work);
+ queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+ i2s_info->work_index++;
+ i2s_info->work_index %= WORK_MAX_NUM;
return 0;
}
@@ -263,17 +266,18 @@ static int imx_rpmsg_pause(struct snd_pcm_substream *substream)
struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
struct i2s_rpmsg_s *rpmsg = &i2s_info->send_msg[substream->stream];
- u8 cmd;
+ u8 index = i2s_info->work_index;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- cmd = I2S_TX_PAUSE;
+ rpmsg->header.cmd = I2S_TX_PAUSE;
else
- cmd = I2S_RX_PAUSE;
+ rpmsg->header.cmd = I2S_RX_PAUSE;
- rpmsg->header.cmd = cmd;
- memcpy(&i2s_info->work_list[cmd].msg, rpmsg,
+ memcpy(&i2s_info->work_list[index].msg, rpmsg,
sizeof(struct i2s_rpmsg_s));
- queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[cmd].work);
+ queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+ i2s_info->work_index++;
+ i2s_info->work_index %= WORK_MAX_NUM;
return 0;
}
@@ -285,17 +289,18 @@ static int imx_rpmsg_terminate_all(struct snd_pcm_substream *substream)
struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
struct i2s_rpmsg_s *rpmsg = &i2s_info->send_msg[substream->stream];
- u8 cmd;
+ u8 index = i2s_info->work_index;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- cmd = I2S_TX_TERMINATE;
+ rpmsg->header.cmd = I2S_TX_TERMINATE;
else
- cmd = I2S_RX_TERMINATE;
+ rpmsg->header.cmd = I2S_RX_TERMINATE;
- rpmsg->header.cmd = cmd;
- memcpy(&i2s_info->work_list[cmd].msg, rpmsg,
+ memcpy(&i2s_info->work_list[index].msg, rpmsg,
sizeof(struct i2s_rpmsg_s));
- queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[cmd].work);
+ queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+ i2s_info->work_index++;
+ i2s_info->work_index %= WORK_MAX_NUM;
return 0;
}