From b83dd26e865e09c8f28fe45074baeead5c21b6fb Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Sat, 12 Oct 2019 14:38:06 -0500 Subject: [PATCH 1/4] soundwire: stream: fix state machine and add state checks The state machine is incorrect, we need to be able to go from STREAM_DEPREPARED to STREAM_PREPARED, e.g. to deal with underflows or suspend/resume, where the .prepare() callback is called after a .trigger (STOP/SUSPEND). Add checks for prepare, enable, disable, deprepared to make sure the client is notified of illegal state machine transitions. Signed-off-by: Pierre-Louis Bossart --- Documentation/driver-api/soundwire/stream.rst | 12 +++--- drivers/soundwire/stream.c | 38 +++++++++++++++++-- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/Documentation/driver-api/soundwire/stream.rst b/Documentation/driver-api/soundwire/stream.rst index 5351bd2f34a870..ca574c4815e153 100644 --- a/Documentation/driver-api/soundwire/stream.rst +++ b/Documentation/driver-api/soundwire/stream.rst @@ -156,12 +156,12 @@ Below shows the SoundWire stream states and state transition diagram. :: +-----------+ +------------+ +----------+ +----------+ | ALLOCATED +---->| CONFIGURED +---->| PREPARED +---->| ENABLED | | STATE | | STATE | | STATE | | STATE | - +-----------+ +------------+ +----------+ +----+-----+ - ^ - | - | - v - +----------+ +------------+ +----+-----+ + +-----------+ +------------+ +-----+----+ +----+-----+ + ^ ^ + | | + _____| | + | v + +----------+ +-----+------+ +----+-----+ | RELEASED |<----------+ DEPREPARED |<-------+ DISABLED | | STATE | | STATE | | STATE | +----------+ +------------+ +----------+ diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index 7f7749ff812054..785b6f56a64607 100644 --- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -1551,15 +1551,21 @@ int sdw_prepare_stream(struct sdw_stream_runtime *stream) return -EINVAL; } - if (stream->state != SDW_STREAM_CONFIGURED) - return 0; - sdw_acquire_bus_lock(stream); + if (stream->state != SDW_STREAM_CONFIGURED && + stream->state != SDW_STREAM_DEPREPARED) { + pr_err("%s: %s: inconsistent state state %d\n", + __func__, stream->name, stream->state); + ret = -EINVAL; + goto state_err; + } + ret = _sdw_prepare_stream(stream); if (ret < 0) pr_err("Prepare for stream:%s failed: %d\n", stream->name, ret); +state_err: sdw_release_bus_lock(stream); return ret; } @@ -1624,10 +1630,19 @@ int sdw_enable_stream(struct sdw_stream_runtime *stream) sdw_acquire_bus_lock(stream); + if (stream->state != SDW_STREAM_PREPARED && + stream->state != SDW_STREAM_DISABLED) { + pr_err("%s: %s: inconsistent state state %d\n", + __func__, stream->name, stream->state); + ret = -EINVAL; + goto state_err; + } + ret = _sdw_enable_stream(stream); if (ret < 0) pr_err("Enable for stream:%s failed: %d\n", stream->name, ret); +state_err: sdw_release_bus_lock(stream); return ret; } @@ -1700,10 +1715,18 @@ int sdw_disable_stream(struct sdw_stream_runtime *stream) sdw_acquire_bus_lock(stream); + if (stream->state != SDW_STREAM_ENABLED) { + pr_err("%s: %s: inconsistent state state %d\n", + __func__, stream->name, stream->state); + ret = -EINVAL; + goto state_err; + } + ret = _sdw_disable_stream(stream); if (ret < 0) pr_err("Disable for stream:%s failed: %d\n", stream->name, ret); +state_err: sdw_release_bus_lock(stream); return ret; } @@ -1758,10 +1781,19 @@ int sdw_deprepare_stream(struct sdw_stream_runtime *stream) } sdw_acquire_bus_lock(stream); + + if (stream->state != SDW_STREAM_DISABLED) { + pr_err("%s: %s: inconsistent state state %d\n", + __func__, stream->name, stream->state); + ret = -EINVAL; + goto state_err; + } + ret = _sdw_deprepare_stream(stream); if (ret < 0) pr_err("De-prepare for stream:%d failed: %d\n", ret, ret); +state_err: sdw_release_bus_lock(stream); return ret; } From 0b4bf13693815fe5a4b2b02bebea7f1707788a14 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Sat, 12 Oct 2019 13:36:08 -0500 Subject: [PATCH 2/4] soundwire: intel: stream deprepare on TRIGGER_STOP/SUSPEND/PAUSE_PUSH ALSA does not have a deprepare step, and calling sdw_deprepare_stream() in the .hw_free step raises all kinds of issues, e.g. with aplay not resuming after system suspend since the stream is already configured. It's just better to call sdw_deprepare_stream() for all transfer stops, and require that the .prepare() callback be used to reconfigure the stream. Signed-off-by: Pierre-Louis Bossart --- drivers/soundwire/intel.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index a61d4cbcbea687..9cf339d23b7c2a 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -875,6 +875,7 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, { struct sdw_cdns_dma_data *dma; int ret; + int err; dma = snd_soc_dai_get_dma_data(dai, substream); if (!dma) { @@ -893,6 +894,16 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: ret = sdw_disable_stream(dma->stream); + + if (!ret) { + err = sdw_deprepare_stream(dma->stream); + if (err) { + dev_err(dai->dev, + "sdw_deprepare_stream: failed %d", err); + ret = err; + } + } + break; default: @@ -919,12 +930,6 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) if (!dma) return -EIO; - ret = sdw_deprepare_stream(dma->stream); - if (ret) { - dev_err(dai->dev, "sdw_deprepare_stream: failed %d", ret); - return ret; - } - ret = sdw_stream_remove_master(&cdns->bus, dma->stream); if (ret < 0) { dev_err(dai->dev, "remove master from stream %s failed: %d\n", From 57099d45b14adbd7f8119ff94bc0f8a884777545 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 14 Oct 2019 17:35:52 +0800 Subject: [PATCH 3/4] soundwire: intel: re-initialize ALH PDIs during suspend/resume transition The .prepare() callback is invoked for underflows or during the system resume transition. In the latter case, the context for the ALH PDIs is lost, and the DSP is not initialized properly either. Keep track of the TRIGGER_SUSPEND transition with a boolean flag, and use it during the .prepare step to check if the ALH PDIs need to be reconfigured. Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart --- drivers/soundwire/cadence_master.h | 3 +++ drivers/soundwire/intel.c | 43 ++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h index 0f108fd31fd943..f03abfe3727be9 100644 --- a/drivers/soundwire/cadence_master.h +++ b/drivers/soundwire/cadence_master.h @@ -81,6 +81,8 @@ struct sdw_cdns_stream_config { * @bus: Bus handle * @stream_type: Stream type * @link_id: Master link id + * @suspend_reinitialize: status flag indicating PDI needs to be reinitialized + * after a TRIGGER_SUSPEND. */ struct sdw_cdns_dma_data { char *name; @@ -89,6 +91,7 @@ struct sdw_cdns_dma_data { struct sdw_bus *bus; enum sdw_stream_type stream_type; int link_id; + bool suspend_reinitialize; }; /** diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 9cf339d23b7c2a..669c278bcc1655 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -117,6 +117,8 @@ struct sdw_intel { struct sdw_cdns cdns; int instance; struct sdw_intel_link_res *link_res; + struct snd_pcm_hw_params *hw_params; + struct sdw_cdns_pdi *pdi; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs; #endif @@ -610,6 +612,7 @@ static int intel_params_stream(struct sdw_intel *sdw, params_data.link_id = link_id; params_data.alh_stream_id = alh_stream_id; + sdw->hw_params = hw_params; if (res->ops && res->ops->params_stream && res->dev) return res->ops->params_stream(res->dev, ¶ms_data); @@ -810,12 +813,14 @@ static int intel_hw_params(struct snd_pcm_substream *substream, goto error; } + dma->suspend_reinitialize = false; + /* do run-time configurations for SHIM, ALH and PDI/PORT */ intel_pdi_shim_configure(sdw, pdi); intel_pdi_alh_configure(sdw, pdi); sdw_cdns_config_stream(cdns, ch, dir, pdi); - + sdw->pdi = pdi; /* Inform DSP about PDI stream number */ ret = intel_params_stream(sdw, substream, dai, params, sdw->instance, @@ -858,7 +863,10 @@ static int intel_hw_params(struct snd_pcm_substream *substream, static int intel_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { + struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); + struct sdw_intel *sdw = cdns_to_intel(cdns); struct sdw_cdns_dma_data *dma; + int ch, dir; dma = snd_soc_dai_get_dma_data(dai, substream); if (!dma) { @@ -867,6 +875,33 @@ static int intel_prepare(struct snd_pcm_substream *substream, return -EIO; } + if (dma->suspend_reinitialize) { + /* + * .prepare() is called when dealing with underflows or + * after system resume. In the latter case, we need to + * re-initialize the ALH settings, which is not needed + * in the underflow case + */ + + /* configure stream */ + ch = params_channels(sdw->hw_params); + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + dir = SDW_DATA_DIR_RX; + else + dir = SDW_DATA_DIR_TX; + + intel_pdi_shim_configure(sdw, sdw->pdi); + intel_pdi_alh_configure(sdw, sdw->pdi); + sdw_cdns_config_stream(cdns, ch, dir, sdw->pdi); + + /* Inform DSP about PDI stream number */ + ret = intel_params_stream(sdw, substream, dai, sdw->hw_params, + sdw->instance, + sdw->pdi->intel_alh_id); + + dma->suspend_reinitialize = false; + } + return sdw_prepare_stream(dma->stream); } @@ -890,8 +925,10 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, ret = sdw_enable_stream(dma->stream); break; - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: + dma->suspend_reinitialize = true; + /* fallthrough */ + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_STOP: ret = sdw_disable_stream(dma->stream); @@ -943,6 +980,8 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) return ret; } + sdw->hw_params = NULL; + sdw->pdi = NULL; sdw_release_stream(dma->stream); return 0; From 43c19f4838fbf7def636320e3a6cab7fababe9fd Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Sat, 12 Oct 2019 12:32:57 -0500 Subject: [PATCH 4/4] [HACK] add traces to debug aplay suspend/resume issue Signed-off-by: Pierre-Louis Bossart --- drivers/soundwire/intel.c | 56 ++++++++++++++++++++++++++++++++++++-- drivers/soundwire/stream.c | 19 +++++++++++++ sound/soc/Makefile | 2 ++ sound/soc/sof/pcm.c | 6 ++++ sound/soc/sof/pm.c | 16 +++++++++++ 5 files changed, 96 insertions(+), 3 deletions(-) diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 669c278bcc1655..2d07267a32541c 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -763,6 +763,8 @@ static int intel_startup(struct snd_pcm_substream *substream, struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); int ret; + dev_err(dai->dev, "%s: %s: start\n", __func__, dai->name); + if (pm_runtime_enabled(cdns->dev)) { ret = pm_runtime_get_sync(cdns->dev); if (ret < 0) { @@ -773,7 +775,11 @@ static int intel_startup(struct snd_pcm_substream *substream, } } - return sdw_stream_setup(substream, dai); + ret = sdw_stream_setup(substream, dai); + + dev_err(dai->dev, "%s: %s: done\n", __func__, dai->name); + + return ret; } static int intel_hw_params(struct snd_pcm_substream *substream, @@ -790,6 +796,8 @@ static int intel_hw_params(struct snd_pcm_substream *substream, int ret; bool pcm = true; + dev_err(dai->dev, "%s: %s: start\n", __func__, dai->name); + dma = snd_soc_dai_get_dma_data(dai, substream); if (!dma) return -EIO; @@ -856,7 +864,10 @@ static int intel_hw_params(struct snd_pcm_substream *substream, dev_err(cdns->dev, "add master to stream failed:%d\n", ret); kfree(pconfig); + error: + + dev_err(dai->dev, "%s: %s: done\n", __func__, dai->name); return ret; } @@ -867,6 +878,9 @@ static int intel_prepare(struct snd_pcm_substream *substream, struct sdw_intel *sdw = cdns_to_intel(cdns); struct sdw_cdns_dma_data *dma; int ch, dir; + int ret; + + dev_err(dai->dev, "%s: %s: start\n", __func__, dai->name); dma = snd_soc_dai_get_dma_data(dai, substream); if (!dma) { @@ -902,7 +916,11 @@ static int intel_prepare(struct snd_pcm_substream *substream, dma->suspend_reinitialize = false; } - return sdw_prepare_stream(dma->stream); + ret = sdw_prepare_stream(dma->stream); + + dev_err(dai->dev, "%s: %s: done\n", __func__, dai->name); + + return ret; } static int intel_trigger(struct snd_pcm_substream *substream, int cmd, @@ -912,6 +930,8 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, int ret; int err; + dev_err(dai->dev, "%s: %s: start\n", __func__, dai->name); + dma = snd_soc_dai_get_dma_data(dai, substream); if (!dma) { dev_err(dai->dev, "failed to get dma data in %s", __func__); @@ -919,13 +939,16 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, } switch (cmd) { + case SNDRV_PCM_TRIGGER_RESUME: + dev_err(dai->dev, "%s: %s: resume\n", __func__, dai->name); + /* fallthrough */ case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - case SNDRV_PCM_TRIGGER_RESUME: ret = sdw_enable_stream(dma->stream); break; case SNDRV_PCM_TRIGGER_SUSPEND: + dev_err(dai->dev, "%s: %s: suspend\n", __func__, dai->name); dma->suspend_reinitialize = true; /* fallthrough */ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: @@ -952,6 +975,9 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, dev_err(dai->dev, "%s trigger %d failed: %d", __func__, cmd, ret); + + dev_err(dai->dev, "%s: %s: done\n", __func__, dai->name); + return ret; } @@ -963,6 +989,8 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) struct sdw_cdns_dma_data *dma; int ret; + dev_err(dai->dev, "%s: %s: start\n", __func__, dai->name); + dma = snd_soc_dai_get_dma_data(dai, substream); if (!dma) return -EIO; @@ -984,6 +1012,8 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) sdw->pdi = NULL; sdw_release_stream(dma->stream); + dev_err(dai->dev, "%s: %s: done\n", __func__, dai->name); + return 0; } @@ -994,6 +1024,8 @@ static void intel_shutdown(struct snd_pcm_substream *substream, struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); int ret; + dev_err(dai->dev, "%s: %s: start\n", __func__, dai->name); + dma = snd_soc_dai_get_dma_data(dai, substream); if (!dma) return; @@ -1009,6 +1041,8 @@ static void intel_shutdown(struct snd_pcm_substream *substream, "pm_runtime_put_autosuspend failed in %s:, ret %d\n", __func__, ret); } + + dev_err(dai->dev, "%s: %s: done\n", __func__, dai->name); } static int intel_pcm_set_sdw_stream(struct snd_soc_dai *dai, @@ -1364,6 +1398,8 @@ static int intel_suspend(struct device *dev) return 0; } + dev_err(dev, "%s start\n", __func__); + if (pm_runtime_status_suspended(dev)) { dev_dbg(dev, "%s: pm_runtime status: suspended\n", @@ -1392,6 +1428,8 @@ static int intel_suspend(struct device *dev) intel_shim_wake(sdw, false); + dev_err(dev, "%s done\n", __func__); + return 0; } @@ -1407,6 +1445,8 @@ static int intel_suspend_runtime(struct device *dev) return 0; } + dev_err(dev, "%s start\n", __func__); + ret = sdw_cdns_enable_interrupt(cdns, false); if (ret < 0) { dev_err(dev, "cannot disable interrupts on suspend\n"); @@ -1421,6 +1461,8 @@ static int intel_suspend_runtime(struct device *dev) intel_shim_wake(sdw, false); + dev_err(dev, "%s done\n", __func__); + return 0; } @@ -1437,6 +1479,8 @@ static int intel_resume(struct device *dev) return 0; } + dev_err(dev, "%s start\n", __func__); + if (md->pm_runtime_suspended) { dev_dbg(dev, "%s: pm_runtime status was suspended, forcing active\n", @@ -1469,6 +1513,8 @@ static int intel_resume(struct device *dev) return ret; } + dev_err(dev, "%s done\n", __func__); + return ret; } @@ -1484,6 +1530,8 @@ static int intel_resume_runtime(struct device *dev) return 0; } + dev_err(dev, "%s start\n", __func__); + ret = intel_init(sdw); if (ret) { dev_err(dev, "%s failed: %d", __func__, ret); @@ -1505,6 +1553,8 @@ static int intel_resume_runtime(struct device *dev) return ret; } + dev_err(dev, "%s done\n", __func__); + return ret; } diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index 785b6f56a64607..a1d2e5217e8aae 100644 --- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -1546,6 +1546,8 @@ int sdw_prepare_stream(struct sdw_stream_runtime *stream) { int ret = 0; + pr_err("%s: %s start\n", __func__, stream->name); + if (!stream) { pr_err("SoundWire: Handle not found for stream\n"); return -EINVAL; @@ -1567,6 +1569,9 @@ int sdw_prepare_stream(struct sdw_stream_runtime *stream) state_err: sdw_release_bus_lock(stream); + + pr_err("%s: %s: done\n", __func__, stream->name); + return ret; } EXPORT_SYMBOL(sdw_prepare_stream); @@ -1623,6 +1628,8 @@ int sdw_enable_stream(struct sdw_stream_runtime *stream) { int ret; + pr_err("%s: %s: start\n", __func__, stream->name); + if (!stream) { pr_err("SoundWire: Handle not found for stream\n"); return -EINVAL; @@ -1644,6 +1651,8 @@ int sdw_enable_stream(struct sdw_stream_runtime *stream) state_err: sdw_release_bus_lock(stream); + + pr_err("%s: %s: done\n", __func__, stream->name); return ret; } EXPORT_SYMBOL(sdw_enable_stream); @@ -1708,6 +1717,8 @@ int sdw_disable_stream(struct sdw_stream_runtime *stream) { int ret; + pr_err("%s: %s: start\n", __func__, stream->name); + if (!stream) { pr_err("SoundWire: Handle not found for stream\n"); return -EINVAL; @@ -1728,6 +1739,9 @@ int sdw_disable_stream(struct sdw_stream_runtime *stream) state_err: sdw_release_bus_lock(stream); + + pr_err("%s: %s: done\n", __func__, stream->name); + return ret; } EXPORT_SYMBOL(sdw_disable_stream); @@ -1775,6 +1789,8 @@ int sdw_deprepare_stream(struct sdw_stream_runtime *stream) { int ret; + pr_err("%s: %s: start\n", __func__, stream->name); + if (!stream) { pr_err("SoundWire: Handle not found for stream\n"); return -EINVAL; @@ -1795,6 +1811,9 @@ int sdw_deprepare_stream(struct sdw_stream_runtime *stream) state_err: sdw_release_bus_lock(stream); + + pr_err("%s: %s: done\n", __func__, stream->name); + return ret; } EXPORT_SYMBOL(sdw_deprepare_stream); diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 861a21b7948443..429add4afe3827 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -1,3 +1,5 @@ +ccflags-y += -DDEBUG + # SPDX-License-Identifier: GPL-2.0 snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-utils.o soc-dai.o soc-component.o snd-soc-core-objs += soc-pcm.o soc-io.o soc-devres.o soc-ops.o diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index d72798d2b3026f..47017ca56c8aed 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -346,6 +346,9 @@ static int sof_pcm_trigger(struct snd_soc_component *component, stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_RELEASE; break; case SNDRV_PCM_TRIGGER_RESUME: + dev_dbg(sdev->dev, "pcm: trigger resume stream %d dir %d cmd %d\n", + spcm->pcm.pcm_id, substream->stream, cmd); + /* set up hw_params */ ret = sof_pcm_prepare(component, substream); if (ret < 0) { @@ -359,6 +362,9 @@ static int sof_pcm_trigger(struct snd_soc_component *component, stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_START; break; case SNDRV_PCM_TRIGGER_SUSPEND: + dev_dbg(sdev->dev, "pcm: trigger suspend stream %d dir %d cmd %d\n", + spcm->pcm.pcm_id, substream->stream, cmd); + /* fallthrough */ case SNDRV_PCM_TRIGGER_STOP: stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP; ipc_first = true; diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index 81e623dfc7e52b..eb9900e709cb99 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -17,6 +17,8 @@ static int sof_restore_kcontrols(struct snd_sof_dev *sdev) int ipc_cmd, ctrl_type; int ret = 0; + dev_err(sdev->dev, "%s\n", __func__); + /* restore kcontrol values */ list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { /* reset readback offset for scontrol after resuming */ @@ -69,6 +71,8 @@ static int sof_restore_pipelines(struct snd_sof_dev *sdev) struct sof_ipc_cmd_hdr *hdr; int ret; + dev_err(sdev->dev, "%s\n", __func__); + /* restore pipeline components */ list_for_each_entry_reverse(swidget, &sdev->widget_list, list) { struct sof_ipc_comp_reply r; @@ -202,6 +206,8 @@ static int sof_send_pm_ipc(struct snd_sof_dev *sdev, int cmd) struct sof_ipc_pm_ctx pm_ctx; struct sof_ipc_reply reply; + dev_err(sdev->dev, "%s\n", __func__); + memset(&pm_ctx, 0, sizeof(pm_ctx)); /* configure ctx save ipc message */ @@ -220,6 +226,7 @@ static int sof_set_hw_params_upon_resume(struct snd_sof_dev *sdev) snd_pcm_state_t state; int dir; + dev_err(sdev->dev, "%s\n", __func__); /* * SOF requires hw_params to be set-up internally upon resume. * So, set the flag to indicate this for those streams that @@ -265,6 +272,8 @@ static int sof_resume(struct device *dev, bool runtime_resume) struct snd_sof_dev *sdev = dev_get_drvdata(dev); int ret; + dev_err(dev, "%s\n", __func__); + /* do nothing if dsp resume callbacks are not set */ if (!sof_ops(sdev)->resume || !sof_ops(sdev)->runtime_resume) return 0; @@ -337,6 +346,8 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) struct snd_sof_dev *sdev = dev_get_drvdata(dev); int ret; + dev_err(dev, "%s\n", __func__); + /* do nothing if dsp suspend callback is not set */ if (!sof_ops(sdev)->suspend) return 0; @@ -393,6 +404,7 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) int snd_sof_runtime_suspend(struct device *dev) { + dev_err(dev, "%s\n", __func__); return sof_suspend(dev, true); } EXPORT_SYMBOL(snd_sof_runtime_suspend); @@ -401,24 +413,28 @@ int snd_sof_runtime_idle(struct device *dev) { struct snd_sof_dev *sdev = dev_get_drvdata(dev); + dev_err(dev, "%s\n", __func__); return snd_sof_dsp_runtime_idle(sdev); } EXPORT_SYMBOL(snd_sof_runtime_idle); int snd_sof_runtime_resume(struct device *dev) { + dev_err(dev, "%s\n", __func__); return sof_resume(dev, true); } EXPORT_SYMBOL(snd_sof_runtime_resume); int snd_sof_resume(struct device *dev) { + dev_err(dev, "%s\n", __func__); return sof_resume(dev, false); } EXPORT_SYMBOL(snd_sof_resume); int snd_sof_suspend(struct device *dev) { + dev_err(dev, "%s\n", __func__); return sof_suspend(dev, false); } EXPORT_SYMBOL(snd_sof_suspend);