Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions sound/soc/sof/intel/hda-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -1324,11 +1324,23 @@ int hda_data_stream_cleanup(struct device *dev, struct snd_dma_buffer *dmab,
struct snd_sof_dev *sdev = dev_get_drvdata(dev);
struct hdac_stream *hstream = hdac_stream(hext_stream);
int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
int ret = 0;
int ret1;
int ret;

if (hstream->direction == SNDRV_PCM_STREAM_PLAYBACK)
ret = hda_dsp_stream_spib_config(sdev, hext_stream, HDA_DSP_SPIB_DISABLE, 0);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is true, that the spib_addr must be set when the SPIB is enabled - which is strange as you are changing an address runtime, but anyways, then would not this be a better and global solution:

diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
index b5d81a3b8b39..0f8807f14fbd 100644
--- a/sound/soc/sof/intel/hda-stream.c
+++ b/sound/soc/sof/intel/hda-stream.c
@@ -198,13 +198,18 @@ int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev,
 
 	mask = (1 << hstream->index);
 
+	/* Reset the spib_addr before disabling SPIB */
+	if (!enable)
+		sof_io_write(sdev, hstream->spib_addr, 0);
+
 	/* enable/disable SPIB for the stream */
 	snd_sof_dsp_update_bits(sdev, HDA_DSP_SPIB_BAR,
 				SOF_HDA_ADSP_REG_CL_SPBFIFO_SPBFCCTL, mask,
 				enable << hstream->index);
 
 	/* set the SPIB value */
-	sof_io_write(sdev, hstream->spib_addr, size);
+	if (enable)
+		sof_io_write(sdev, hstream->spib_addr, size);
 
 	return 0;
 }

else
/*
* Reset SPIB. The SPIB value will only take effect when SPIB is enabled,
* That is why we need to set the value with HDA_DSP_SPIB_ENABLE
*/
ret = hda_dsp_stream_spib_config(sdev, hext_stream, HDA_DSP_SPIB_ENABLE, 0);
if (ret < 0) {
dev_err(sdev->dev, "%s: failed to reset SPIB: %d\n", __func__, ret);
}

ret1 = hda_dsp_stream_spib_config(sdev, hext_stream, HDA_DSP_SPIB_DISABLE, 0);
if (!ret)
ret = ret1;
Comment thread
bardliao marked this conversation as resolved.

Comment on lines +1334 to +1342
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hda_data_stream_cleanup() now returns an error if the SPIB reset/disable fails, which changes behavior for capture streams (previously ret stayed 0 unless direction was PLAYBACK). Since SPIB appears optional and other call sites treat SPIB config as best-effort (e.g. hda_dsp_stream_hw_free() calls hda_dsp_stream_spib_config(...DISABLE...) and still returns 0 at hda-stream.c:770-774), consider not propagating SPIB failures from cleanup (e.g. only attempt when sdev->bar[HDA_DSP_SPIB_BAR] is present, and/or keep ret at 0 unless later cleanup steps fail).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

@bardliao bardliao May 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original code also propagates HDA_DSP_SPIB_DISABLE error. I think we need to propagate the error on capture, too.

if (hstream->direction == SNDRV_PCM_STREAM_CAPTURE)
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
SOF_HDA_SD_CTL_DMA_START, 0);

Expand Down
Loading