summaryrefslogtreecommitdiff
path: root/sound/soc/fsl/imx-pcm-rpmsg.c
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@nxp.com>2018-09-19 16:17:58 +0800
committerDong Aisheng <aisheng.dong@nxp.com>2019-11-25 15:53:10 +0800
commit4fd0f03d0b2d8d3206c6c26661ba553a8c0ac6cf (patch)
treed384f55aeaf0a5985fcb3aa3beef15d290289197 /sound/soc/fsl/imx-pcm-rpmsg.c
parent6ef9128b309dbf826a174e415a0052bb0d6ec153 (diff)
MLK-19760: ASoC: imx-pcm-rpmsg: fix resume back quickly after resume
With LPA mode, if the period size is small, the timer for query buffer pointer will be triggered immediately after suspend, the MU interrupt will resume the system quickly. This patch is to disable timer when suspend. Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com> (cherry picked from commit 9c5e78cf50855bd73f2b5c3dc8bc48f8a0907b39)
Diffstat (limited to 'sound/soc/fsl/imx-pcm-rpmsg.c')
-rw-r--r--sound/soc/fsl/imx-pcm-rpmsg.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/sound/soc/fsl/imx-pcm-rpmsg.c b/sound/soc/fsl/imx-pcm-rpmsg.c
index 0c2e7e392b79..a7e4818050b3 100644
--- a/sound/soc/fsl/imx-pcm-rpmsg.c
+++ b/sound/soc/fsl/imx-pcm-rpmsg.c
@@ -22,6 +22,7 @@
#include "imx-pcm.h"
#include "fsl_rpmsg_i2s.h"
+#include "../../core/pcm_local.h"
struct i2s_info *i2s_info_g;
@@ -297,8 +298,17 @@ static void imx_rpmsg_pcm_dma_complete(void *arg)
rpmsg->recv_msg.param.buffer_offset =
rpmsg2->recv_msg.param.buffer_tail
* snd_pcm_lib_period_bytes(substream);
-
- snd_pcm_period_elapsed(substream);
+ /*
+ * With suspend state, which is not running state, M4 will trigger
+ * system resume with PERIOD_DONE command, at this moment, the
+ * snd_pcm_period_elapsed can't update the hw ptr. so call
+ * snd_pcm_update_hw_ptr directly for this special case.
+ *
+ */
+ if (!snd_pcm_running(substream) && rpmsg_i2s->force_lpa)
+ snd_pcm_update_hw_ptr(substream);
+ else
+ snd_pcm_period_elapsed(substream);
}
static int imx_rpmsg_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
@@ -466,7 +476,9 @@ int imx_rpmsg_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
+ struct i2s_info *i2s_info = &rpmsg_i2s->i2s_info;
int ret;
+ int time_msec;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -476,8 +488,13 @@ int imx_rpmsg_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
imx_rpmsg_async_issue_pending(substream);
break;
case SNDRV_PCM_TRIGGER_RESUME:
- if (rpmsg_i2s->force_lpa)
+ if (rpmsg_i2s->force_lpa) {
+ time_msec = min(500,
+ (int)(runtime->period_size*1000/runtime->rate));
+ mod_timer(&i2s_info->stream_timer[substream->stream],
+ jiffies + msecs_to_jiffies(time_msec));
break;
+ }
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
imx_rpmsg_restart(substream);
break;
@@ -487,7 +504,8 @@ int imx_rpmsg_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
imx_rpmsg_pause(substream);
else
imx_rpmsg_terminate_all(substream);
- }
+ } else
+ del_timer(&i2s_info->stream_timer[substream->stream]);
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
imx_rpmsg_pause(substream);