[alsa-devel] [RFC PATCH v2 1/2] ASoC: refine ASoC hdmi audio suspend/resume

Takashi Iwai tiwai at suse.de
Fri Jan 11 16:43:38 CET 2019


On Fri, 11 Jan 2019 15:24:30 +0100,
Takashi Iwai wrote:
> 
> On Fri, 11 Jan 2019 14:34:34 +0100,
> Takashi Iwai wrote:
> > 
> > On Fri, 11 Jan 2019 06:20:23 +0100,
> > Yang, Libin wrote:
> > > 
> > > The below patch may have a small confliction that the trigger will be 
> > > called twice as our SOF has already call snd_pcm_suspend() in card
> > > suspend.
> > 
> > It should be no problem, snd_pcm_suspend() can be called multiple
> > times.  If it's already suspended, just nothing happens.
> 
> Thinking of this problem again, does a patch like below work instead?
> This looks like a better and more generic solution.
> 
> What I'm not quite sure is whether the device suspend order between
> PCM device and HD-audio codec device is guaranteed.  I guess yes,
> because the PCM device is registered always after the codec.  But ASoC
> might have another weirdness :)

... and further reading revealed that my afraid is right -- ASoC is
another beast.  Basically PM in ASoC requires *not* to be done by the
usual device PM callbacks.  snd_soc_suspend() does the whole suspend
jobs sequentially.  So, what you need for Intel ASoC driver is to do
suspend/resume with the component callbacks instead of device PM ops.
Currently the plumbing of hdac-hdmi driver is in a half-baked state.

> If this patch works, basically we can get rid of all external callers
> of snd_pcm_suspend() & co.  That'll be a nice cleanup.

OTOH, the statement above is still true for non-ASoC drivers.  So we'd
end up needing an extra flag or such to prevent the PCM device PM ops
for ASoC, while using this for the rest.


thanks,

Takashi

> 
> 
> thanks,
> 
> Takashi
> 
> ---
> diff --git a/sound/core/pcm.c b/sound/core/pcm.c
> index 01b9d62eef14..d8d57336b8b8 100644
> --- a/sound/core/pcm.c
> +++ b/sound/core/pcm.c
> @@ -683,6 +683,25 @@ static inline int snd_pcm_substream_proc_done(struct snd_pcm_substream *substrea
>  
>  static const struct attribute_group *pcm_dev_attr_groups[];
>  
> +#ifdef CONFIG_PM_SLEEP
> +static int do_pcm_suspend(struct device *dev)
> +{
> +	struct snd_pcm_str *pstr = container_of(dev, struct snd_pcm_str, dev);
> +
> +	snd_pcm_suspend_all(pstr->pcm);
> +	return 0;
> +}
> +#endif
> +
> +static const struct dev_pm_ops pcm_dev_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(do_pcm_suspend, NULL)
> +};
> +
> +static const struct device_type pcm_dev_type = {
> +	.name = "pcm",
> +	.pm = &pcm_dev_pm_ops,
> +};
> +
>  /**
>   * snd_pcm_new_stream - create a new PCM stream
>   * @pcm: the pcm instance
> @@ -713,6 +732,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
>  
>  	snd_device_initialize(&pstr->dev, pcm->card);
>  	pstr->dev.groups = pcm_dev_attr_groups;
> +	pstr->dev.type = &pcm_dev_type;
>  	dev_set_name(&pstr->dev, "pcmC%iD%i%c", pcm->card->number, pcm->device,
>  		     stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');
>  


More information about the Alsa-devel mailing list