Skip to content

Commit de94efb

Browse files
ujfalusikv2019i
authored andcommitted
ASoC: SOF: sof-client: Add support for clients not managed by pm framework
Some SOF client can be of 'passive' type, meaning that they do not handle PM framework callbacks by themselves but rely on the auxiliary driver's suspend and resume callbacks to be notified about the core's suspend or resume event. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
1 parent 69cfa48 commit de94efb

3 files changed

Lines changed: 70 additions & 1 deletion

File tree

sound/soc/sof/pm.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,9 @@ static int sof_resume(struct device *dev, bool runtime_resume)
167167
return ret;
168168
}
169169

170+
/* Notify clients not managed by pm framework about core resume */
171+
sof_resume_clients(sdev);
172+
170173
/* notify DSP of system resume */
171174
ret = sof_send_pm_ctx_ipc(sdev, SOF_IPC_PM_CTX_RESTORE);
172175
if (ret < 0)
@@ -180,6 +183,7 @@ static int sof_resume(struct device *dev, bool runtime_resume)
180183
static int sof_suspend(struct device *dev, bool runtime_suspend)
181184
{
182185
struct snd_sof_dev *sdev = dev_get_drvdata(dev);
186+
pm_message_t pm_state;
183187
u32 target_state = 0;
184188
int ret;
185189

@@ -205,16 +209,23 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
205209
}
206210

207211
target_state = snd_sof_dsp_power_target(sdev);
212+
pm_state.event = target_state;
208213

209214
/* Skip to platform-specific suspend if DSP is entering D0 */
210-
if (target_state == SOF_DSP_PM_D0)
215+
if (target_state == SOF_DSP_PM_D0) {
216+
/* Notify clients not managed by pm framework about core suspend */
217+
sof_suspend_clients(sdev, pm_state);
211218
goto suspend;
219+
}
212220

213221
sof_tear_down_pipelines(sdev, false);
214222

215223
/* release trace */
216224
snd_sof_release_trace(sdev);
217225

226+
/* Notify clients not managed by pm framework about core suspend */
227+
sof_suspend_clients(sdev, pm_state);
228+
218229
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE)
219230
/* cache debugfs contents during runtime suspend */
220231
if (runtime_suspend)

sound/soc/sof/sof-client.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,52 @@ int sof_client_ipc_tx_message(struct sof_client_dev *cdev, void *ipc_msg,
169169
}
170170
EXPORT_SYMBOL_NS_GPL(sof_client_ipc_tx_message, SND_SOC_SOF_CLIENT);
171171

172+
int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state)
173+
{
174+
struct auxiliary_driver *adrv;
175+
struct sof_client_dev *cdev;
176+
177+
mutex_lock(&sdev->ipc_client_mutex);
178+
179+
list_for_each_entry(cdev, &sdev->ipc_client_list, list) {
180+
/* Skip devices without loaded driver */
181+
if (!cdev->auxdev.dev.driver)
182+
continue;
183+
184+
adrv = to_auxiliary_drv(cdev->auxdev.dev.driver);
185+
if (adrv->suspend)
186+
adrv->suspend(&cdev->auxdev, state);
187+
}
188+
189+
mutex_unlock(&sdev->ipc_client_mutex);
190+
191+
return 0;
192+
}
193+
EXPORT_SYMBOL_NS_GPL(sof_suspend_clients, SND_SOC_SOF_CLIENT);
194+
195+
int sof_resume_clients(struct snd_sof_dev *sdev)
196+
{
197+
struct auxiliary_driver *adrv;
198+
struct sof_client_dev *cdev;
199+
200+
mutex_lock(&sdev->ipc_client_mutex);
201+
202+
list_for_each_entry(cdev, &sdev->ipc_client_list, list) {
203+
/* Skip devices without loaded driver */
204+
if (!cdev->auxdev.dev.driver)
205+
continue;
206+
207+
adrv = to_auxiliary_drv(cdev->auxdev.dev.driver);
208+
if (adrv->resume)
209+
adrv->resume(&cdev->auxdev);
210+
}
211+
212+
mutex_unlock(&sdev->ipc_client_mutex);
213+
214+
return 0;
215+
}
216+
EXPORT_SYMBOL_NS_GPL(sof_resume_clients, SND_SOC_SOF_CLIENT);
217+
172218
struct dentry *sof_client_get_debugfs_root(struct sof_client_dev *cdev)
173219
{
174220
return cdev->sdev->debugfs_root;

sound/soc/sof/sof-priv.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,8 @@ int sof_register_clients(struct snd_sof_dev *sdev);
676676
void sof_unregister_clients(struct snd_sof_dev *sdev);
677677
void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *msg_buf);
678678
void sof_client_fw_state_dispatcher(struct snd_sof_dev *sdev);
679+
int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state);
680+
int sof_resume_clients(struct snd_sof_dev *sdev);
679681
#else /* CONFIG_SND_SOC_SOF_CLIENT */
680682
static inline int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name,
681683
u32 id, const void *data, size_t size)
@@ -704,6 +706,16 @@ static inline void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *
704706
static inline void sof_client_fw_state_dispatcher(struct snd_sof_dev *sdev)
705707
{
706708
}
709+
710+
static inline int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state)
711+
{
712+
return 0;
713+
}
714+
715+
static inline int sof_resume_clients(struct snd_sof_dev *sdev)
716+
{
717+
return 0;
718+
}
707719
#endif /* CONFIG_SND_SOC_SOF_CLIENT */
708720

709721
#endif

0 commit comments

Comments
 (0)