Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 150
ASoC: SOF: handle paused streams during system suspend#3119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -191,7 +191,7 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) | ||
| if (sdev->fw_state != SOF_FW_BOOT_COMPLETE) | ||
| goto suspend; | ||
| /* set restore_stream for all streams during system suspend */ | ||
| /* prepare for streams to be resumed properly upon resume */ | ||
ranj063 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| if (!runtime_suspend) { | ||
| ret = sof_set_hw_params_upon_resume(sdev->dev); | ||
| if (ret < 0) { | ||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -718,6 +718,55 @@ int sof_set_up_pipelines(struct snd_sof_dev *sdev, bool verify) | ||||
| return 0; | ||||
| } | ||||
| /* | ||||
| * Free the PCM, its associated widgets and set the prepared flag to false for all PCMs that | ||||
| * did not get suspended(ex: paused streams) so the widgets can be set up again during resume. | ||||
| */ | ||||
| static int sof_tear_down_left_over_pipelines(struct snd_sof_dev *sdev) | ||||
| { | ||||
| struct snd_sof_widget *swidget; | ||||
| struct snd_sof_pcm *spcm; | ||||
| int dir, ret; | ||||
| /* | ||||
| * free all PCMs and their associated DAPM widgets if their connected DAPM widget | ||||
| * list is not NULL. This should only be true for paused streams at this point. | ||||
| * This is equivalent to the handling of FE DAI suspend trigger for running streams. | ||||
| */ | ||||
| list_for_each_entry(spcm, &sdev->pcm_list, list) | ||||
| for_each_pcm_streams(dir) { | ||||
| struct snd_pcm_substream *substream = spcm->stream[dir].substream; | ||||
| if (!substream || !substream->runtime) | ||||
| continue; | ||||
| if (spcm->stream[dir].list) { | ||||
| ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm); | ||||
| if (ret < 0) | ||||
| return ret; | ||||
| ret = sof_widget_list_free(sdev, spcm, dir); | ||||
| if (ret < 0) { | ||||
| dev_err(sdev->dev, "failed to free widgets during suspend\n"); | ||||
| return ret; | ||||
| } | ||||
| } | ||||
| } | ||||
plbossart marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||||
| /* | ||||
| * free any left over DAI widgets. This is equivalent to the handling of suspend trigger | ||||
| * for the BE DAI for running streams. | ||||
| */ | ||||
| list_for_each_entry(swidget, &sdev->widget_list, list) | ||||
| if (WIDGET_IS_DAI(swidget->id) && swidget->use_count == 1) { | ||||
| ret = sof_widget_free(sdev, swidget); | ||||
| if (ret < 0) | ||||
| return ret; | ||||
| } | ||||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am still unclear on how the tests above apply to the PAUSED case only. the 'free the paused PCMS and associated DAPM widgets' is at best done with an indirect set of criteria?
| ||||
| intsnd_soc_dpcm_can_be_params(structsnd_soc_pcm_runtime*fe, |
I dont see a second BE hw_params in SOF and I'm thinking it is because of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is still a corner case where the application could do multiple hw_params on the two devices, before starting one.
I think it'd need dedicated hacks to test.
But even if that happens, I think the only issue is at the CPU dai level. if we do an internal hw_free to keep the refcounts consistent, regardless of what happens in the ALSA/ASoC core, we should be in good shape. It's done for SoundWire, I am not sure about the other DAIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is still a corner case where the application could do multiple hw_params on the two devices, before starting one.
I think it'd need dedicated hacks to test.
agree. Let me add a fix for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just added a patch for this @plbossart
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wording "unusual" is a bit unusual. :) I mean it is allowed and it does happen, so this is fixing a bug. But yeah, I get the point.