Skip to content

Commit 511ef68

Browse files
committed
ASoC: SOF: PM: destroy pipelines during device suspend
In order to make the SOF suspend/resume callbacks balanced, the pipelines should be destroyed before the DSP is suspended. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
1 parent f732090 commit 511ef68

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

sound/soc/sof/pm.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
136136
if (!sof_ops(sdev)->suspend)
137137
return 0;
138138

139+
/* remove pipelines */
140+
sof_destroy_pipelines(dev);
141+
139142
/* release trace */
140143
snd_sof_release_trace(sdev);
141144

sound/soc/sof/sof-audio.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,52 @@ int sof_set_hw_params_upon_resume(struct device *dev)
5353
return snd_sof_dsp_hw_params_upon_resume(sdev);
5454
}
5555

56+
int sof_destroy_pipelines(struct device *dev)
57+
{
58+
struct snd_sof_dev *sdev = dev_get_drvdata(dev);
59+
struct snd_sof_widget *swidget;
60+
struct sof_ipc_free ipc_free;
61+
struct sof_ipc_reply reply;
62+
int ret = 0;
63+
64+
list_for_each_entry_reverse(swidget, &sdev->widget_list, list) {
65+
memset(&ipc_free, 0, sizeof(ipc_free));
66+
67+
/* skip if there is no private data */
68+
if (!swidget->private)
69+
continue;
70+
71+
/* configure ipc free message */
72+
ipc_free.hdr.size = sizeof(ipc_free);
73+
ipc_free.hdr.cmd = SOF_IPC_GLB_TPLG_MSG;
74+
ipc_free.id = swidget->comp_id;
75+
76+
switch (swidget->id) {
77+
case snd_soc_dapm_scheduler:
78+
ipc_free.hdr.cmd |= SOF_IPC_TPLG_PIPE_FREE;
79+
break;
80+
case snd_soc_dapm_buffer:
81+
ipc_free.hdr.cmd |= SOF_IPC_TPLG_BUFFER_FREE;
82+
break;
83+
default:
84+
ipc_free.hdr.cmd |= SOF_IPC_TPLG_COMP_FREE;
85+
break;
86+
}
87+
ret = sof_ipc_tx_message(sdev->ipc, ipc_free.hdr.cmd,
88+
&ipc_free, sizeof(ipc_free), &reply,
89+
sizeof(reply));
90+
if (ret < 0) {
91+
dev_err(sdev->dev,
92+
"error: failed to free widget type %d with ID: %d\n",
93+
swidget->widget->id, swidget->comp_id);
94+
95+
return ret;
96+
}
97+
}
98+
99+
return ret;
100+
}
101+
56102
static int sof_restore_kcontrols(struct device *dev)
57103
{
58104
struct snd_sof_dev *sdev = dev_get_drvdata(dev);

sound/soc/sof/sof-audio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ int snd_sof_ipc_set_get_comp_data(struct snd_sof_control *scontrol,
201201

202202
/* PM */
203203
int sof_restore_pipelines(struct device *dev);
204+
int sof_destroy_pipelines(struct device *dev);
204205
int sof_set_hw_params_upon_resume(struct device *dev);
205206
bool snd_sof_dsp_d0i3_on_suspend(struct snd_sof_dev *sdev);
206207

0 commit comments

Comments
 (0)