FAILED: patch "[PATCH] ASoC: SOF: ipc4-topology: Refresh copier IPC payload before" failed to apply to 6.12-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x 0c0e418dbcf0582bf80d8dbfd9b306607c065992
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026082017-backspace-rectify-6ec7@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 0c0e418dbcf0582bf80d8dbfd9b306607c065992 Mon Sep 17 00:00:00 2001
From: Peter Ujfalusi <[email protected]>
Date: Thu, 30 Jul 2026 08:48:22 +0300
Subject: [PATCH] ASoC: SOF: ipc4-topology: Refresh copier IPC payload before
widget setup
The ipc_config_data buffer for copier widgets is built once during ipc_prepare (called from sof_pcm_setup_connected_widgets) and cached for reuse. For host copiers this buffer contains the copier_data with gtw_cfg.node_id (host DMA ID). For DAI copiers it additionally includes a dma_config_tlv trailer with stream_id and dma_channel_id for HDA link DMA.
On suspend/resume, both host and link DMA streams are released and re-allocated with potentially different stream tags. The underlying copier_data and dma_config_tlv structures are correctly updated by host_config and sdw_hda_dai_hw_params respectively. However, since the widget list (spcm->stream[].list) persists across suspend, sof_pcm_hw_params skips sof_pcm_setup_connected_widgets and ipc_prepare never runs again to rebuild ipc_config_data. The stale cached payload is then sent to firmware with boot-time DMA channel assignments, causing DMA channel conflicts that lead to firmware errors and crashes.
Fix this by refreshing copier_data and dma_config_tlv portions of ipc_config_data in sof_ipc4_widget_setup right before the IPC message is sent. This ensures the payload always reflects the current DMA state regardless of whether ipc_prepare ran.
For DAI copiers, the gtw_cfg.config_length in copier_data is temporarily inflated to include the TLV size (matching the ipc_config_data layout) before copying, then restored, mirroring what sof_ipc4_prepare_copier_module does when first building the buffer.
sound/soc/sof/ipc4-topology.c +33 -0
@@ -3204,6 +3204,15 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget ipc_size = ipc4_copier->ipc_config_size; ipc_data = ipc4_copier->ipc_config_data; +/* +* Refresh copier_data in ipc_config_data for host copiers. +* The node_id may have been updated by host_config after +* ipc_prepare, e.g. when host stream tags change after a +* suspend/resume cycle. +*/ +if (swidget->id != snd_soc_dapm_buffer) +memcpy (ipc_data, &ipc4_copier->data,sizeof (ipc4_copier->data)); + msg = &ipc4_copier->msg;break ; }
@@ -3212,6 +3221,9 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget {struct snd_sof_dai *dai = swidget->private;struct sof_ipc4_copier *ipc4_copier = dai->private; +struct sof_ipc4_copier_data *copier_data; +u32 gtw_cfg_config_length; +u32 tlv_size; pipeline = pipe_widget->private;if (pipeline->use_chain_dma)
@@ -3220,6 +3232,27 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget ipc_size = ipc4_copier->ipc_config_size; ipc_data = ipc4_copier->ipc_config_data; +/* +* Refresh copier_data and dma_config_tlv in ipc_config_data. +* These may have been updated after ipc_prepare, e.g. when +* link DMA stream tags change after a suspend/resume cycle. +* +* copier_data->gtw_cfg.config_length does not include the +* TLV size (it was restored after sof_ipc4_prepare_copier_module), +* so temporarily inflate it to match the ipc_config_data layout. +*/ + copier_data = &ipc4_copier->data; + gtw_cfg_config_length = copier_data->gtw_cfg.config_length *4 ; + tlv_size = ipc_size -sizeof (*copier_data) - gtw_cfg_config_length; + + copier_data->gtw_cfg.config_length += tlv_size /4 ; +memcpy (ipc_data, copier_data,sizeof (*copier_data)); + copier_data->gtw_cfg.config_length = gtw_cfg_config_length /4 ; + +if (tlv_size) +memcpy (ipc_data +sizeof (*copier_data) + gtw_cfg_config_length, + &ipc4_copier->dma_config_tlv, tlv_size); + msg = &ipc4_copier->msg;break ; }
Peter Ujfalusi
maintainerPATCH 1/1 ASoC: SOF: ipc4-topology: Refresh copier IPC payload before widget setup
The ipc_config_data buffer for copier widgets is built once during ipc_prepare (called from sof_pcm_setup_connected_widgets) and cached for reuse. For host copiers this buffer contains the copier_data with gtw_cfg.node_id (host DMA ID). For DAI copiers it additionally includes a dma_config_tlv trailer with stream_id and dma_channel_id for HDA link DMA.
On suspend/resume, both host and link DMA streams are released and re-allocated with potentially different stream tags. The underlying copier_data and dma_config_tlv structures are correctly updated by host_config and sdw_hda_dai_hw_params respectively. However, since the widget list (spcm->stream[].list) persists across suspend, sof_pcm_hw_params skips sof_pcm_setup_connected_widgets and ipc_prepare never runs again to rebuild ipc_config_data. The stale cached payload is then sent to firmware with boot-time DMA channel assignments, causing DMA channel conflicts that lead to firmware errors and crashes.
Fix this by refreshing copier_data and dma_config_tlv portions of ipc_config_data in sof_ipc4_widget_setup right before the IPC message is sent. This ensures the payload always reflects the current DMA state regardless of whether ipc_prepare ran.
For DAI copiers, the gtw_cfg.config_length in copier_data is temporarily inflated to include the TLV size (matching the ipc_config_data layout) before copying, then restored, mirroring what sof_ipc4_prepare_copier_module does when first building the buffer.
--- sound/soc/sof/ipc4-topology.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
sound/soc/sof/ipc4-topology.c +33 -0
@@ -2654,6 +2654,15 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget ipc_size = ipc4_copier->ipc_config_size; ipc_data = ipc4_copier->ipc_config_data; +/* +* Refresh copier_data in ipc_config_data for host copiers. +* The node_id may have been updated by host_config after +* ipc_prepare, e.g. when host stream tags change after a +* suspend/resume cycle. +*/ +if (swidget->id != snd_soc_dapm_buffer) +memcpy (ipc_data, &ipc4_copier->data,sizeof (ipc4_copier->data)); + msg = &ipc4_copier->msg;break ; }
@@ -2662,6 +2671,9 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget {struct snd_sof_dai *dai = swidget->private;struct sof_ipc4_copier *ipc4_copier = dai->private; +struct sof_ipc4_copier_data *copier_data; +u32 gtw_cfg_config_length; +u32 tlv_size; pipeline = pipe_widget->private;if (pipeline->use_chain_dma)
@@ -2670,6 +2682,27 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget ipc_size = ipc4_copier->ipc_config_size; ipc_data = ipc4_copier->ipc_config_data; +/* +* Refresh copier_data and dma_config_tlv in ipc_config_data. +* These may have been updated after ipc_prepare, e.g. when +* link DMA stream tags change after a suspend/resume cycle. +* +* copier_data->gtw_cfg.config_length does not include the +* TLV size (it was restored after sof_ipc4_prepare_copier_module), +* so temporarily inflate it to match the ipc_config_data layout. +*/ + copier_data = &ipc4_copier->data; + gtw_cfg_config_length = copier_data->gtw_cfg.config_length *4 ; + tlv_size = ipc_size -sizeof (*copier_data) - gtw_cfg_config_length; + + copier_data->gtw_cfg.config_length += tlv_size /4 ; +memcpy (ipc_data, copier_data,sizeof (*copier_data)); + copier_data->gtw_cfg.config_length = gtw_cfg_config_length /4 ; + +if (tlv_size) +memcpy (ipc_data +sizeof (*copier_data) + gtw_cfg_config_length, + &ipc4_copier->dma_config_tlv, tlv_size); + msg = &ipc4_copier->msg;break ; }
Signature · 1 line
2.55.0