1e149ca29SPierre-Louis Bossart // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
28920153cSLiam Girdwood //
38920153cSLiam Girdwood // This file is provided under a dual BSD/GPLv2 license. When using or
48920153cSLiam Girdwood // redistributing this file, you may do so under either license.
58920153cSLiam Girdwood //
68920153cSLiam Girdwood // Copyright(c) 2018 Intel Corporation. All rights reserved.
78920153cSLiam Girdwood //
88920153cSLiam Girdwood // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
98920153cSLiam Girdwood //
108920153cSLiam Girdwood
118920153cSLiam Girdwood #include "ops.h"
128920153cSLiam Girdwood #include "sof-priv.h"
13ee1e79b7SRanjani Sridharan #include "sof-audio.h"
148920153cSLiam Girdwood
15700d1677SRanjani Sridharan /*
16700d1677SRanjani Sridharan * Helper function to determine the target DSP state during
17700d1677SRanjani Sridharan * system suspend. This function only cares about the device
18700d1677SRanjani Sridharan * D-states. Platform-specific substates, if any, should be
19700d1677SRanjani Sridharan * handled by the platform-specific parts.
20700d1677SRanjani Sridharan */
snd_sof_dsp_power_target(struct snd_sof_dev * sdev)21700d1677SRanjani Sridharan static u32 snd_sof_dsp_power_target(struct snd_sof_dev *sdev)
22700d1677SRanjani Sridharan {
23700d1677SRanjani Sridharan u32 target_dsp_state;
24700d1677SRanjani Sridharan
25700d1677SRanjani Sridharan switch (sdev->system_suspend_target) {
269d2d4627SPierre-Louis Bossart case SOF_SUSPEND_S5:
279d2d4627SPierre-Louis Bossart case SOF_SUSPEND_S4:
289d2d4627SPierre-Louis Bossart /* DSP should be in D3 if the system is suspending to S3+ */
29700d1677SRanjani Sridharan case SOF_SUSPEND_S3:
30700d1677SRanjani Sridharan /* DSP should be in D3 if the system is suspending to S3 */
31700d1677SRanjani Sridharan target_dsp_state = SOF_DSP_PM_D3;
32700d1677SRanjani Sridharan break;
33700d1677SRanjani Sridharan case SOF_SUSPEND_S0IX:
34700d1677SRanjani Sridharan /*
35700d1677SRanjani Sridharan * Currently, the only criterion for retaining the DSP in D0
36700d1677SRanjani Sridharan * is that there are streams that ignored the suspend trigger.
37700d1677SRanjani Sridharan * Additional criteria such Soundwire clock-stop mode and
38700d1677SRanjani Sridharan * device suspend latency considerations will be added later.
39700d1677SRanjani Sridharan */
40700d1677SRanjani Sridharan if (snd_sof_stream_suspend_ignored(sdev))
41700d1677SRanjani Sridharan target_dsp_state = SOF_DSP_PM_D0;
42700d1677SRanjani Sridharan else
43700d1677SRanjani Sridharan target_dsp_state = SOF_DSP_PM_D3;
44700d1677SRanjani Sridharan break;
45700d1677SRanjani Sridharan default:
46700d1677SRanjani Sridharan /* This case would be during runtime suspend */
47700d1677SRanjani Sridharan target_dsp_state = SOF_DSP_PM_D3;
48700d1677SRanjani Sridharan break;
49700d1677SRanjani Sridharan }
50700d1677SRanjani Sridharan
51700d1677SRanjani Sridharan return target_dsp_state;
52700d1677SRanjani Sridharan }
53700d1677SRanjani Sridharan
548920153cSLiam Girdwood #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE)
sof_cache_debugfs(struct snd_sof_dev * sdev)558920153cSLiam Girdwood static void sof_cache_debugfs(struct snd_sof_dev *sdev)
568920153cSLiam Girdwood {
578920153cSLiam Girdwood struct snd_sof_dfsentry *dfse;
588920153cSLiam Girdwood
598920153cSLiam Girdwood list_for_each_entry(dfse, &sdev->dfsentry_list, list) {
608920153cSLiam Girdwood
618920153cSLiam Girdwood /* nothing to do if debugfs buffer is not IO mem */
628920153cSLiam Girdwood if (dfse->type == SOF_DFSENTRY_TYPE_BUF)
638920153cSLiam Girdwood continue;
648920153cSLiam Girdwood
658920153cSLiam Girdwood /* cache memory that is only accessible in D0 */
668920153cSLiam Girdwood if (dfse->access_type == SOF_DEBUGFS_ACCESS_D0_ONLY)
678920153cSLiam Girdwood memcpy_fromio(dfse->cache_buf, dfse->io_mem,
688920153cSLiam Girdwood dfse->size);
698920153cSLiam Girdwood }
708920153cSLiam Girdwood }
718920153cSLiam Girdwood #endif
728920153cSLiam Girdwood
sof_resume(struct device * dev,bool runtime_resume)738920153cSLiam Girdwood static int sof_resume(struct device *dev, bool runtime_resume)
748920153cSLiam Girdwood {
758920153cSLiam Girdwood struct snd_sof_dev *sdev = dev_get_drvdata(dev);
76510758eeSPeter Ujfalusi const struct sof_ipc_pm_ops *pm_ops = sof_ipc_get_ops(sdev, pm);
77510758eeSPeter Ujfalusi const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
7861e285caSRanjani Sridharan u32 old_state = sdev->dsp_power_state.state;
798920153cSLiam Girdwood int ret;
808920153cSLiam Girdwood
818920153cSLiam Girdwood /* do nothing if dsp resume callbacks are not set */
82c26fde3bSDaniel Baluta if (!runtime_resume && !sof_ops(sdev)->resume)
83c26fde3bSDaniel Baluta return 0;
84c26fde3bSDaniel Baluta
85c26fde3bSDaniel Baluta if (runtime_resume && !sof_ops(sdev)->runtime_resume)
868920153cSLiam Girdwood return 0;
878920153cSLiam Girdwood
88410e5e55SPierre-Louis Bossart /* DSP was never successfully started, nothing to resume */
89410e5e55SPierre-Louis Bossart if (sdev->first_boot)
90410e5e55SPierre-Louis Bossart return 0;
91410e5e55SPierre-Louis Bossart
928920153cSLiam Girdwood /*
938920153cSLiam Girdwood * if the runtime_resume flag is set, call the runtime_resume routine
948920153cSLiam Girdwood * or else call the system resume routine
958920153cSLiam Girdwood */
968920153cSLiam Girdwood if (runtime_resume)
978920153cSLiam Girdwood ret = snd_sof_dsp_runtime_resume(sdev);
988920153cSLiam Girdwood else
998920153cSLiam Girdwood ret = snd_sof_dsp_resume(sdev);
1008920153cSLiam Girdwood if (ret < 0) {
1018920153cSLiam Girdwood dev_err(sdev->dev,
1028920153cSLiam Girdwood "error: failed to power up DSP after resume\n");
1038920153cSLiam Girdwood return ret;
1048920153cSLiam Girdwood }
1058920153cSLiam Girdwood
10628d40e7aSPeter Ujfalusi if (sdev->dspless_mode_selected) {
10728d40e7aSPeter Ujfalusi sof_set_fw_state(sdev, SOF_DSPLESS_MODE);
10828d40e7aSPeter Ujfalusi return 0;
10928d40e7aSPeter Ujfalusi }
11028d40e7aSPeter Ujfalusi
111fc907cc5SRanjani Sridharan /*
112fc907cc5SRanjani Sridharan * Nothing further to be done for platforms that support the low power
113249ee180SLibin Yang * D0 substate. Resume trace and return when resuming from
114249ee180SLibin Yang * low-power D0 substate
115fc907cc5SRanjani Sridharan */
116fc907cc5SRanjani Sridharan if (!runtime_resume && sof_ops(sdev)->set_power_state &&
117249ee180SLibin Yang old_state == SOF_DSP_PM_D0) {
1181dedbe4fSPeter Ujfalusi ret = sof_fw_trace_resume(sdev);
119249ee180SLibin Yang if (ret < 0)
120249ee180SLibin Yang /* non fatal */
121249ee180SLibin Yang dev_warn(sdev->dev,
122249ee180SLibin Yang "failed to enable trace after resume %d\n", ret);
123fb9a8119SRanjani Sridharan return 0;
124249ee180SLibin Yang }
125fb9a8119SRanjani Sridharan
12658a5c9a4SPeter Ujfalusi sof_set_fw_state(sdev, SOF_FW_BOOT_PREPARE);
1276ca5cecbSRanjani Sridharan
1288920153cSLiam Girdwood /* load the firmware */
1298920153cSLiam Girdwood ret = snd_sof_load_firmware(sdev);
1308920153cSLiam Girdwood if (ret < 0) {
1318920153cSLiam Girdwood dev_err(sdev->dev,
1328920153cSLiam Girdwood "error: failed to load DSP firmware after resume %d\n",
1338920153cSLiam Girdwood ret);
134e2406275SPeter Ujfalusi sof_set_fw_state(sdev, SOF_FW_BOOT_FAILED);
1358920153cSLiam Girdwood return ret;
1368920153cSLiam Girdwood }
1378920153cSLiam Girdwood
13858a5c9a4SPeter Ujfalusi sof_set_fw_state(sdev, SOF_FW_BOOT_IN_PROGRESS);
1396ca5cecbSRanjani Sridharan
1406ca5cecbSRanjani Sridharan /*
1416ca5cecbSRanjani Sridharan * Boot the firmware. The FW boot status will be modified
1426ca5cecbSRanjani Sridharan * in snd_sof_run_firmware() depending on the outcome.
1436ca5cecbSRanjani Sridharan */
1448920153cSLiam Girdwood ret = snd_sof_run_firmware(sdev);
1458920153cSLiam Girdwood if (ret < 0) {
1468920153cSLiam Girdwood dev_err(sdev->dev,
1478920153cSLiam Girdwood "error: failed to boot DSP firmware after resume %d\n",
1488920153cSLiam Girdwood ret);
149e2406275SPeter Ujfalusi sof_set_fw_state(sdev, SOF_FW_BOOT_FAILED);
1508920153cSLiam Girdwood return ret;
1518920153cSLiam Girdwood }
1528920153cSLiam Girdwood
153758f24d4SLibin Yang /* resume DMA trace */
1541dedbe4fSPeter Ujfalusi ret = sof_fw_trace_resume(sdev);
1558920153cSLiam Girdwood if (ret < 0) {
1568920153cSLiam Girdwood /* non fatal */
1578920153cSLiam Girdwood dev_warn(sdev->dev,
1588920153cSLiam Girdwood "warning: failed to init trace after resume %d\n",
1598920153cSLiam Girdwood ret);
1608920153cSLiam Girdwood }
1618920153cSLiam Girdwood
1628920153cSLiam Girdwood /* restore pipelines */
163510758eeSPeter Ujfalusi if (tplg_ops && tplg_ops->set_up_all_pipelines) {
16431cd6e46SRanjani Sridharan ret = tplg_ops->set_up_all_pipelines(sdev, false);
1658920153cSLiam Girdwood if (ret < 0) {
16631cd6e46SRanjani Sridharan dev_err(sdev->dev, "Failed to restore pipeline after resume %d\n", ret);
167*171b53beSKai Vehmanen goto setup_fail;
1688920153cSLiam Girdwood }
16931cd6e46SRanjani Sridharan }
1708920153cSLiam Girdwood
1711069967aSPeter Ujfalusi /* Notify clients not managed by pm framework about core resume */
1721069967aSPeter Ujfalusi sof_resume_clients(sdev);
1731069967aSPeter Ujfalusi
1748920153cSLiam Girdwood /* notify DSP of system resume */
175657774acSRanjani Sridharan if (pm_ops && pm_ops->ctx_restore) {
176657774acSRanjani Sridharan ret = pm_ops->ctx_restore(sdev);
1778920153cSLiam Girdwood if (ret < 0)
178657774acSRanjani Sridharan dev_err(sdev->dev, "ctx_restore IPC error during resume: %d\n", ret);
179657774acSRanjani Sridharan }
1808920153cSLiam Girdwood
181*171b53beSKai Vehmanen setup_fail:
182*171b53beSKai Vehmanen #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE)
183*171b53beSKai Vehmanen if (ret < 0) {
184*171b53beSKai Vehmanen /*
185*171b53beSKai Vehmanen * Debugfs cannot be read in runtime suspend, so cache
186*171b53beSKai Vehmanen * the contents upon failure. This allows to capture
187*171b53beSKai Vehmanen * possible DSP coredump information.
188*171b53beSKai Vehmanen */
189*171b53beSKai Vehmanen sof_cache_debugfs(sdev);
190*171b53beSKai Vehmanen }
191*171b53beSKai Vehmanen #endif
192*171b53beSKai Vehmanen
1938920153cSLiam Girdwood return ret;
1948920153cSLiam Girdwood }
1958920153cSLiam Girdwood
sof_suspend(struct device * dev,bool runtime_suspend)1968920153cSLiam Girdwood static int sof_suspend(struct device *dev, bool runtime_suspend)
1978920153cSLiam Girdwood {
1988920153cSLiam Girdwood struct snd_sof_dev *sdev = dev_get_drvdata(dev);
199510758eeSPeter Ujfalusi const struct sof_ipc_pm_ops *pm_ops = sof_ipc_get_ops(sdev, pm);
200510758eeSPeter Ujfalusi const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
2011069967aSPeter Ujfalusi pm_message_t pm_state;
2026f95eec6SRanjani Sridharan u32 target_state = snd_sof_dsp_power_target(sdev);
2030b186bb0SDaniel Baluta u32 old_state = sdev->dsp_power_state.state;
2048920153cSLiam Girdwood int ret;
2058920153cSLiam Girdwood
2068920153cSLiam Girdwood /* do nothing if dsp suspend callback is not set */
207c26fde3bSDaniel Baluta if (!runtime_suspend && !sof_ops(sdev)->suspend)
208c26fde3bSDaniel Baluta return 0;
209c26fde3bSDaniel Baluta
210c26fde3bSDaniel Baluta if (runtime_suspend && !sof_ops(sdev)->runtime_suspend)
2118920153cSLiam Girdwood return 0;
2128920153cSLiam Girdwood
2130b186bb0SDaniel Baluta /* we need to tear down pipelines only if the DSP hardware is
2140b186bb0SDaniel Baluta * active, which happens for PCI devices. if the device is
2150b186bb0SDaniel Baluta * suspended, it is brought back to full power and then
2160b186bb0SDaniel Baluta * suspended again
2170b186bb0SDaniel Baluta */
2180b186bb0SDaniel Baluta if (tplg_ops && tplg_ops->tear_down_all_pipelines && (old_state == SOF_DSP_PM_D0))
219d185e068SRanjani Sridharan tplg_ops->tear_down_all_pipelines(sdev, false);
220d185e068SRanjani Sridharan
2216ca5cecbSRanjani Sridharan if (sdev->fw_state != SOF_FW_BOOT_COMPLETE)
222fb9a8119SRanjani Sridharan goto suspend;
2238920153cSLiam Girdwood
224a1ce6e43SRanjani Sridharan /* prepare for streams to be resumed properly upon resume */
2257077a07aSRanjani Sridharan if (!runtime_suspend) {
2268e84b6a4SRanjani Sridharan ret = snd_sof_dsp_hw_params_upon_resume(sdev);
2277077a07aSRanjani Sridharan if (ret < 0) {
2287077a07aSRanjani Sridharan dev_err(sdev->dev,
2297077a07aSRanjani Sridharan "error: setting hw_params flag during suspend %d\n",
2307077a07aSRanjani Sridharan ret);
2317077a07aSRanjani Sridharan return ret;
2327077a07aSRanjani Sridharan }
2337077a07aSRanjani Sridharan }
2348920153cSLiam Girdwood
2351069967aSPeter Ujfalusi pm_state.event = target_state;
236fb9a8119SRanjani Sridharan
23761e285caSRanjani Sridharan /* suspend DMA trace */
2381069967aSPeter Ujfalusi sof_fw_trace_suspend(sdev, pm_state);
2391dedbe4fSPeter Ujfalusi
2401069967aSPeter Ujfalusi /* Notify clients not managed by pm framework about core suspend */
2411069967aSPeter Ujfalusi sof_suspend_clients(sdev, pm_state);
242fb9a8119SRanjani Sridharan
2431069967aSPeter Ujfalusi /* Skip to platform-specific suspend if DSP is entering D0 */
244fb9a8119SRanjani Sridharan if (target_state == SOF_DSP_PM_D0)
245758f24d4SLibin Yang goto suspend;
2461dedbe4fSPeter Ujfalusi
247fb9a8119SRanjani Sridharan #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE)
2481069967aSPeter Ujfalusi /* cache debugfs contents during runtime suspend */
2491069967aSPeter Ujfalusi if (runtime_suspend)
2501069967aSPeter Ujfalusi sof_cache_debugfs(sdev);
2518920153cSLiam Girdwood #endif
2528920153cSLiam Girdwood /* notify DSP of upcoming power down */
2538920153cSLiam Girdwood if (pm_ops && pm_ops->ctx_save) {
2548920153cSLiam Girdwood ret = pm_ops->ctx_save(sdev);
2558920153cSLiam Girdwood if (ret == -EBUSY || ret == -EAGAIN) {
2568920153cSLiam Girdwood /*
257657774acSRanjani Sridharan * runtime PM has logic to handle -EBUSY/-EAGAIN so
258657774acSRanjani Sridharan * pass these errors up
259e2eba551SKai Vehmanen */
260e2eba551SKai Vehmanen dev_err(sdev->dev, "ctx_save IPC error during suspend: %d\n", ret);
261e2eba551SKai Vehmanen return ret;
262e2eba551SKai Vehmanen } else if (ret < 0) {
263e2eba551SKai Vehmanen /* FW in unexpected state, continue to power down */
264657774acSRanjani Sridharan dev_warn(sdev->dev, "ctx_save IPC error: %d, proceeding with suspend\n",
2658920153cSLiam Girdwood ret);
266e2eba551SKai Vehmanen }
267e2eba551SKai Vehmanen }
268657774acSRanjani Sridharan
269e2eba551SKai Vehmanen suspend:
2708920153cSLiam Girdwood
271657774acSRanjani Sridharan /* return if the DSP was not probed successfully */
2728920153cSLiam Girdwood if (sdev->fw_state == SOF_FW_BOOT_NOT_STARTED)
273fb9a8119SRanjani Sridharan return 0;
2746ca5cecbSRanjani Sridharan
2756ca5cecbSRanjani Sridharan /* platform-specific suspend */
2766ca5cecbSRanjani Sridharan if (runtime_suspend)
2776ca5cecbSRanjani Sridharan ret = snd_sof_dsp_runtime_suspend(sdev);
2786ca5cecbSRanjani Sridharan else
279fb9a8119SRanjani Sridharan ret = snd_sof_dsp_suspend(sdev, target_state);
2808920153cSLiam Girdwood if (ret < 0)
2811c38c922SFred Oh dev_err(sdev->dev,
2828920153cSLiam Girdwood "error: failed to power down DSP during suspend %d\n",
28361e285caSRanjani Sridharan ret);
2848920153cSLiam Girdwood
2858920153cSLiam Girdwood /* Do not reset FW state if DSP is in D0 */
2868920153cSLiam Girdwood if (target_state == SOF_DSP_PM_D0)
2878920153cSLiam Girdwood return ret;
2888920153cSLiam Girdwood
28961e285caSRanjani Sridharan /* reset FW state */
29061e285caSRanjani Sridharan sof_set_fw_state(sdev, SOF_FW_BOOT_NOT_STARTED);
291fb9a8119SRanjani Sridharan sdev->enabled_cores_mask = 0;
292fb9a8119SRanjani Sridharan
2936ca5cecbSRanjani Sridharan return ret;
29458a5c9a4SPeter Ujfalusi }
295b640e8a4SKai Vehmanen
snd_sof_dsp_power_down_notify(struct snd_sof_dev * sdev)2966ca5cecbSRanjani Sridharan int snd_sof_dsp_power_down_notify(struct snd_sof_dev *sdev)
2978920153cSLiam Girdwood {
2988920153cSLiam Girdwood const struct sof_ipc_pm_ops *pm_ops = sof_ipc_get_ops(sdev, pm);
2998920153cSLiam Girdwood
3003541aef1SMarcin Rajwa /* Notify DSP of upcoming power down */
3013541aef1SMarcin Rajwa if (sof_ops(sdev)->remove && pm_ops && pm_ops->ctx_save)
302510758eeSPeter Ujfalusi return pm_ops->ctx_save(sdev);
303657774acSRanjani Sridharan
3043541aef1SMarcin Rajwa return 0;
305657774acSRanjani Sridharan }
306657774acSRanjani Sridharan
snd_sof_runtime_suspend(struct device * dev)3073541aef1SMarcin Rajwa int snd_sof_runtime_suspend(struct device *dev)
3083541aef1SMarcin Rajwa {
3093541aef1SMarcin Rajwa return sof_suspend(dev, true);
3103541aef1SMarcin Rajwa }
3118920153cSLiam Girdwood EXPORT_SYMBOL(snd_sof_runtime_suspend);
3128920153cSLiam Girdwood
snd_sof_runtime_idle(struct device * dev)3138920153cSLiam Girdwood int snd_sof_runtime_idle(struct device *dev)
3148920153cSLiam Girdwood {
3158920153cSLiam Girdwood struct snd_sof_dev *sdev = dev_get_drvdata(dev);
3168920153cSLiam Girdwood
31762fde977SKai Vehmanen return snd_sof_dsp_runtime_idle(sdev);
31862fde977SKai Vehmanen }
31962fde977SKai Vehmanen EXPORT_SYMBOL(snd_sof_runtime_idle);
32062fde977SKai Vehmanen
snd_sof_runtime_resume(struct device * dev)32162fde977SKai Vehmanen int snd_sof_runtime_resume(struct device *dev)
32262fde977SKai Vehmanen {
32362fde977SKai Vehmanen return sof_resume(dev, true);
32462fde977SKai Vehmanen }
3258920153cSLiam Girdwood EXPORT_SYMBOL(snd_sof_runtime_resume);
3268920153cSLiam Girdwood
snd_sof_resume(struct device * dev)3278920153cSLiam Girdwood int snd_sof_resume(struct device *dev)
3288920153cSLiam Girdwood {
3298920153cSLiam Girdwood return sof_resume(dev, false);
3308920153cSLiam Girdwood }
3318920153cSLiam Girdwood EXPORT_SYMBOL(snd_sof_resume);
3328920153cSLiam Girdwood
snd_sof_suspend(struct device * dev)3338920153cSLiam Girdwood int snd_sof_suspend(struct device *dev)
3348920153cSLiam Girdwood {
3358920153cSLiam Girdwood return sof_suspend(dev, false);
3368920153cSLiam Girdwood }
3378920153cSLiam Girdwood EXPORT_SYMBOL(snd_sof_suspend);
3388920153cSLiam Girdwood
snd_sof_prepare(struct device * dev)3398920153cSLiam Girdwood int snd_sof_prepare(struct device *dev)
3408920153cSLiam Girdwood {
3418920153cSLiam Girdwood struct snd_sof_dev *sdev = dev_get_drvdata(dev);
3420b50b3b1SKeyon Jie const struct sof_dev_desc *desc = sdev->pdata->desc;
3430b50b3b1SKeyon Jie
3440b50b3b1SKeyon Jie /* will suspend to S3 by default */
3450b50b3b1SKeyon Jie sdev->system_suspend_target = SOF_SUSPEND_S3;
34643437d04SDaniel Baluta
34743437d04SDaniel Baluta /*
34843437d04SDaniel Baluta * if the firmware is crashed or boot failed then we try to aim for S3
34943437d04SDaniel Baluta * to reboot the firmware
35043437d04SDaniel Baluta */
3514e1f8648SPeter Ujfalusi if (sdev->fw_state == SOF_FW_CRASHED ||
352b54b3a4eSPeter Ujfalusi sdev->fw_state == SOF_FW_BOOT_FAILED)
353b54b3a4eSPeter Ujfalusi return 0;
3544e1f8648SPeter Ujfalusi
355b54b3a4eSPeter Ujfalusi if (!desc->use_acpi_target_states)
356b54b3a4eSPeter Ujfalusi return 0;
3574e1f8648SPeter Ujfalusi
3584e1f8648SPeter Ujfalusi #if defined(CONFIG_ACPI)
35943437d04SDaniel Baluta switch (acpi_target_system_state()) {
36043437d04SDaniel Baluta case ACPI_STATE_S0:
3610b50b3b1SKeyon Jie sdev->system_suspend_target = SOF_SUSPEND_S0IX;
3620b50b3b1SKeyon Jie break;
363a9330845SPierre-Louis Bossart case ACPI_STATE_S1:
364a9330845SPierre-Louis Bossart case ACPI_STATE_S2:
365043ae13bSRanjani Sridharan case ACPI_STATE_S3:
366a9330845SPierre-Louis Bossart sdev->system_suspend_target = SOF_SUSPEND_S3;
367a9330845SPierre-Louis Bossart break;
368a9330845SPierre-Louis Bossart case ACPI_STATE_S4:
369a9330845SPierre-Louis Bossart sdev->system_suspend_target = SOF_SUSPEND_S4;
370a9330845SPierre-Louis Bossart break;
371a9330845SPierre-Louis Bossart case ACPI_STATE_S5:
3729d2d4627SPierre-Louis Bossart sdev->system_suspend_target = SOF_SUSPEND_S5;
3739d2d4627SPierre-Louis Bossart break;
3749d2d4627SPierre-Louis Bossart default:
3759d2d4627SPierre-Louis Bossart break;
3769d2d4627SPierre-Louis Bossart }
3779d2d4627SPierre-Louis Bossart #endif
378a9330845SPierre-Louis Bossart
379a9330845SPierre-Louis Bossart return 0;
380a9330845SPierre-Louis Bossart }
3810b50b3b1SKeyon Jie EXPORT_SYMBOL(snd_sof_prepare);
3820b50b3b1SKeyon Jie
snd_sof_complete(struct device * dev)3830b50b3b1SKeyon Jie void snd_sof_complete(struct device *dev)
3840b50b3b1SKeyon Jie {
3850b50b3b1SKeyon Jie struct snd_sof_dev *sdev = dev_get_drvdata(dev);
3860b50b3b1SKeyon Jie
3870b50b3b1SKeyon Jie sdev->system_suspend_target = SOF_SUSPEND_NONE;
3880b50b3b1SKeyon Jie }
3890b50b3b1SKeyon Jie EXPORT_SYMBOL(snd_sof_complete);
3900b50b3b1SKeyon Jie