summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorJarkko Nikula <jarkko.nikula@linux.intel.com>2014-08-11 14:15:38 +0300
committerMark Brown <broonie@linaro.org>2014-08-11 13:40:24 +0100
commitb80d19c166c4f086eefa05308ab0cb28e43c4ca2 (patch)
tree357891403022f6088c9a3ca3a7b78d800ccc1626 /sound
parent9246539bdda4206c53be1045778b642f1c8137e4 (diff)
downloadlinux-0-day-b80d19c166c4f086eefa05308ab0cb28e43c4ca2.tar.gz
linux-0-day-b80d19c166c4f086eefa05308ab0cb28e43c4ca2.tar.xz
ASoC: Intel: Restore Baytrail ADSP streams only when ADSP was in reset
There is no need to restore and restart PCM streams in case ADSP didn't reach reset and power off state during system suspend/resume cycle. In that case stream is still active but paused and firmware doesn't allow allocating a new stream before paused stream is freed. ADSP remains active in case suspend sequence didn't go to suspend_late stage. This can happen when either suspend sequence is aborted by a wakeup or by letting only devices suspend by "echo devices >/sys/power/pm_test". Currently stream restoring fails in these suspend cases. Fix this by adding a flag that indicates is complete stream reinitialization needed or is it enough to resume paused stream. Flag is set when we know that ADSP reached suspend_late. Initial fix to this issue came from Fang Yang. I modified it a little and forward ported it to top of two other suspend/resume patches from me. Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> Tested-by: Borun Fu <borun.fu@intel.com> Cc: yang fang <yang.a.fang@intel.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/intel/sst-baytrail-pcm.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/sound/soc/intel/sst-baytrail-pcm.c b/sound/soc/intel/sst-baytrail-pcm.c
index eb7b31e135659..eab1c7d851878 100644
--- a/sound/soc/intel/sst-baytrail-pcm.c
+++ b/sound/soc/intel/sst-baytrail-pcm.c
@@ -59,6 +59,9 @@ struct sst_byt_priv_data {
/* DAI data */
struct sst_byt_pcm_data pcm[BYT_PCM_COUNT];
+
+ /* flag indicating is stream context restore needed after suspend */
+ bool restore_stream;
};
/* this may get called several times by oss emulation */
@@ -184,7 +187,10 @@ static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
sst_byt_stream_start(byt, pcm_data->stream, 0);
break;
case SNDRV_PCM_TRIGGER_RESUME:
- schedule_work(&pcm_data->work);
+ if (pdata->restore_stream == true)
+ schedule_work(&pcm_data->work);
+ else
+ sst_byt_stream_resume(byt, pcm_data->stream);
break;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
sst_byt_stream_resume(byt, pcm_data->stream);
@@ -193,6 +199,7 @@ static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
sst_byt_stream_stop(byt, pcm_data->stream);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
+ pdata->restore_stream = false;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
sst_byt_stream_pause(byt, pcm_data->stream);
break;
@@ -407,6 +414,7 @@ static const struct snd_soc_component_driver byt_dai_component = {
static int sst_byt_pcm_dev_suspend_late(struct device *dev)
{
struct sst_pdata *sst_pdata = dev_get_platdata(dev);
+ struct sst_byt_priv_data *priv_data = dev_get_drvdata(dev);
int ret;
dev_dbg(dev, "suspending late\n");
@@ -417,6 +425,8 @@ static int sst_byt_pcm_dev_suspend_late(struct device *dev)
return ret;
}
+ priv_data->restore_stream = true;
+
return ret;
}