From 0c0e418dbcf0582bf80d8dbfd9b306607c065992 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 30 Jul 2026 08:48:22 +0300 Subject: [PATCH 01/20] 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. Fixes: e9c6b118de1a ("ASoC: SOF: make dma_config_tlv be an array") Cc: stable@vger.kernel.org Link: https://github.com/thesofproject/sof/issues/10700 Link: https://github.com/thesofproject/sof/issues/10955 Signed-off-by: Peter Ujfalusi Reviewed-by: Kai Vehmanen Reviewed-by: Liam Girdwood Link: https://patch.msgid.link/20260730054822.5913-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 95ad5266b0c6..6fdfb667cce8 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -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; } From ae63720dd7c3647d64f7a85e5e1870f90eb569d6 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 30 Jul 2026 10:17:24 +0300 Subject: [PATCH 02/20] ASoC: SOF: topology: Use acpi mach from the machine driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The parameters may be changed by the sof_sdw machine driver is the SOC_SDW_PCH_DMIC quirk is set. Use the mach_params from the machine driver to ensure the sof_sdw_get_tplg_files() function select the right function topologies. Fixes: 2fbeff33381c ("ASoC: Intel: add sof_sdw_get_tplg_files ops") Cc: stable@vger.kernel.org Signed-off-by: Bard Liao Reviewed-by: Péter Ujfalusi Reviewed-by: Ranjani Sridharan Signed-off-by: Peter Ujfalusi Link: https://patch.msgid.link/20260730071724.22296-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/common/sof-function-topology-lib.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/common/sof-function-topology-lib.c b/sound/soc/intel/common/sof-function-topology-lib.c index 2f2c902ef90c..b6e5a40b78cc 100644 --- a/sound/soc/intel/common/sof-function-topology-lib.c +++ b/sound/soc/intel/common/sof-function-topology-lib.c @@ -31,7 +31,12 @@ enum tplg_device_id { int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_mach *mach, const char *prefix, const char ***tplg_files, bool best_effort) { - struct snd_soc_acpi_mach_params mach_params = mach->mach_params; + struct snd_soc_acpi_mach *card_mach = dev_get_platdata(card->dev); + /* + * Use the acpi mach from the machine driver because the machine driver + * may change the dmic_num based on the machine driver quirk. + */ + struct snd_soc_acpi_mach_params mach_params = card_mach->mach_params; struct snd_soc_dai_link *dai_link; const struct firmware *fw; char platform[SOF_INTEL_PLATFORM_NAME_MAX]; From e780e4917d43683224812400fe3dc4816fceba75 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 30 Jul 2026 11:59:14 +0300 Subject: [PATCH 03/20] ASoC: SOF: sof-audio: Fix error path in sof_widget_setup_unlocked() If either tplg_ops->dai_config or widget_kcontrol_setup fail during widget setup we would double decrement the use_count of the widget because the sof_widget_free_unlocked() would be called twice, similarly the core_put would be invoked twice as well. Since the use_count and core_put() is handled within the widget_free function we need to return without falling through the pipe_widget_free label. The fixes tag is picked to the last change around this part of the code which is adequately old enough for backporting purposes. Link: https://github.com/thesofproject/sof/issues/10826 Fixes: 31ed8da1c8e5 ("ASoC: SOF: sof-audio: Modify logic for enabling/disabling topology cores") Cc: stable@vger.kernel.org Signed-off-by: Peter Ujfalusi Reviewed-by: Bard Liao Link: https://patch.msgid.link/20260730085914.27546-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/sof-audio.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index acf56607bc9c..24614e506019 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -146,7 +146,6 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev, { const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg); struct snd_sof_pipeline *spipe = swidget->spipe; - bool use_count_decremented = false; int ret; int i; @@ -225,9 +224,10 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev, return 0; widget_free: - /* widget use_count will be decremented by sof_widget_free() */ + /* widget use_count and core_put handled by sof_widget_free() */ sof_widget_free_unlocked(sdev, swidget); - use_count_decremented = true; + return ret; + pipe_widget_free: if (swidget->id != snd_soc_dapm_scheduler) { sof_widget_free_unlocked(sdev, swidget->spipe->pipe_widget); @@ -242,8 +242,7 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev, } } use_count_dec: - if (!use_count_decremented) - swidget->use_count--; + swidget->use_count--; return ret; } From 992eb0dfbc4f594d60ae57974efa835bfac34d1e Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 30 Jul 2026 09:25:18 +0800 Subject: [PATCH 04/20] ASoC/soundwire: Intel: reset the PCMSyCM registers in hda_sdw_bpt_close MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resetting the PCMSyCM registers is required for Intel SoundWire stream. The same procedure is done in sdw_hda_dai_hw_params() for the normal SoundWire stream, too. Signed-off-by: Bard Liao Reviewed-by: Péter Ujfalusi Reviewed-by: Liam Girdwood Reviewed-by: Pierre-Louis Bossart Acked-by: Vinod Koul Link: https://patch.msgid.link/20260730012518.2180906-1-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- drivers/soundwire/intel_ace2x.c | 4 +++- include/sound/hda-sdw-bpt.h | 5 +++-- sound/soc/sof/intel/hda-sdw-bpt.c | 31 ++++++++++++++++++++++++++++--- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2x.c index b37933efac5d..63f131d5682b 100644 --- a/drivers/soundwire/intel_ace2x.c +++ b/drivers/soundwire/intel_ace2x.c @@ -261,6 +261,7 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave * __func__, str_read_write(command), ret); ret1 = hda_sdw_bpt_close(cdns->dev->parent, /* PCI device */ + sdw->instance, sdw->bpt_ctx.bpt_tx_stream, &sdw->bpt_ctx.dmab_tx_bdl, sdw->bpt_ctx.bpt_rx_stream, &sdw->bpt_ctx.dmab_rx_bdl); if (ret1 < 0) @@ -295,7 +296,8 @@ static void intel_ace2x_bpt_close_stream(struct sdw_intel *sdw, struct sdw_slave struct sdw_cdns *cdns = &sdw->cdns; int ret; - ret = hda_sdw_bpt_close(cdns->dev->parent /* PCI device */, sdw->bpt_ctx.bpt_tx_stream, + ret = hda_sdw_bpt_close(cdns->dev->parent /* PCI device */, sdw->instance, + sdw->bpt_ctx.bpt_tx_stream, &sdw->bpt_ctx.dmab_tx_bdl, sdw->bpt_ctx.bpt_rx_stream, &sdw->bpt_ctx.dmab_rx_bdl); if (ret < 0) diff --git a/include/sound/hda-sdw-bpt.h b/include/sound/hda-sdw-bpt.h index 9b654c31829a..e24a549f7d49 100644 --- a/include/sound/hda-sdw-bpt.h +++ b/include/sound/hda-sdw-bpt.h @@ -27,7 +27,7 @@ int hda_sdw_bpt_send_async(struct device *dev, struct hdac_ext_stream *bpt_tx_st int hda_sdw_bpt_wait(struct device *dev, struct hdac_ext_stream *bpt_tx_stream, struct hdac_ext_stream *bpt_rx_stream); -int hda_sdw_bpt_close(struct device *dev, struct hdac_ext_stream *bpt_tx_stream, +int hda_sdw_bpt_close(struct device *dev, int link_id, struct hdac_ext_stream *bpt_tx_stream, struct snd_dma_buffer *dmab_tx_bdl, struct hdac_ext_stream *bpt_rx_stream, struct snd_dma_buffer *dmab_rx_bdl); @@ -58,7 +58,8 @@ static inline int hda_sdw_bpt_wait(struct device *dev, struct hdac_ext_stream *b return -EOPNOTSUPP; } -static inline int hda_sdw_bpt_close(struct device *dev, struct hdac_ext_stream *bpt_tx_stream, +static inline int hda_sdw_bpt_close(struct device *dev, int link_id, + struct hdac_ext_stream *bpt_tx_stream, struct snd_dma_buffer *dmab_tx_bdl, struct hdac_ext_stream *bpt_rx_stream, struct snd_dma_buffer *dmab_rx_bdl) diff --git a/sound/soc/sof/intel/hda-sdw-bpt.c b/sound/soc/sof/intel/hda-sdw-bpt.c index 728ffe7ae54d..7351a0870725 100644 --- a/sound/soc/sof/intel/hda-sdw-bpt.c +++ b/sound/soc/sof/intel/hda-sdw-bpt.c @@ -322,7 +322,8 @@ int hda_sdw_bpt_open(struct device *dev, int link_id, struct hdac_ext_stream **b __func__, ret); close: - ret1 = hda_sdw_bpt_close(dev, *bpt_tx_stream, dmab_tx_bdl, *bpt_rx_stream, dmab_rx_bdl); + ret1 = hda_sdw_bpt_close(dev, link_id, *bpt_tx_stream, dmab_tx_bdl, + *bpt_rx_stream, dmab_rx_bdl); if (ret1 < 0) dev_err(dev, "%s: hda_sdw_bpt_close failed: %d\n", __func__, ret1); @@ -447,14 +448,38 @@ int hda_sdw_bpt_wait(struct device *dev, struct hdac_ext_stream *bpt_tx_stream, } EXPORT_SYMBOL_NS(hda_sdw_bpt_wait, "SND_SOC_SOF_INTEL_HDA_SDW_BPT"); -int hda_sdw_bpt_close(struct device *dev, struct hdac_ext_stream *bpt_tx_stream, +int hda_sdw_bpt_close(struct device *dev, int link_id, struct hdac_ext_stream *bpt_tx_stream, struct snd_dma_buffer *dmab_tx_bdl, struct hdac_ext_stream *bpt_rx_stream, struct snd_dma_buffer *dmab_rx_bdl) { + struct snd_sof_dev *sdev = dev_get_drvdata(dev); int ret; int ret1; - ret = hda_sdw_bpt_dma_deprepare(dev, bpt_rx_stream, dmab_rx_bdl); + /* + * In the case of SoundWire we need to reset the PCMSyCM registers. + * Need to continue depreparing the DMA buffers even if this fails. + */ + ret = hdac_bus_eml_sdw_map_stream_ch(sof_to_bus(sdev), link_id, + 0, /* PDI0 */ + 0, 0, SNDRV_PCM_STREAM_PLAYBACK); + if (ret < 0) + dev_err(dev, "%s: hdac_bus_eml_sdw_map_stream_ch failed %d for PDI0\n", + __func__, ret); + + ret1 = hdac_bus_eml_sdw_map_stream_ch(sof_to_bus(sdev), link_id, + 1, /* PDI1 */ + 0, 0, SNDRV_PCM_STREAM_CAPTURE); + if (ret1 < 0) { + dev_err(dev, "%s: hdac_bus_eml_sdw_map_stream_ch failed %d for PDI1\n", + __func__, ret1); + if (!ret) + ret = ret1; + } + + ret1 = hda_sdw_bpt_dma_deprepare(dev, bpt_rx_stream, dmab_rx_bdl); + if (!ret) + ret = ret1; ret1 = hda_sdw_bpt_dma_deprepare(dev, bpt_tx_stream, dmab_tx_bdl); if (!ret) From 38417f5fc8e3323218c19bd7e419eec4fb0697bd Mon Sep 17 00:00:00 2001 From: Zhang Heng Date: Thu, 30 Jul 2026 20:39:20 +0800 Subject: [PATCH 05/20] ASoC: amd: yc: Add DMI quirk for HP Victus Laptop 16-e1xxx Add DMI quirk to enable ACP6x sound card for HP Victus by HP Laptop 16-e1xxx, which fixes microphone not working issue. Without this quirk, the DMIC on acp6x device is not properly enabled, causing the microphone to not work. Link: https://bugzilla.kernel.org/show_bug.cgi?id=218926 Link: https://github.com/CuerdOS/linux-kernel-nhs/commit/b29ba27a0ed672664071b4b345e63b62a419d31d Signed-off-by: Zhang Heng Reported-by: CuerdOS Dev Team Signed-off-by: CuerdOS Dev Team Link: https://patch.msgid.link/20260730123920.104525-1-zhangheng@kylinos.cn Signed-off-by: Mark Brown --- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index de5c895e9fbd..b62dd77b588d 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -724,6 +724,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_BOARD_NAME, "8E35"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "Victus by HP Laptop 16-e1xxx"), + } + }, { .driver_data = &acp6x_card, .matches = { From 17661c67b206612cb3ba65d5ae726cd2015d0a53 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 30 Jul 2026 14:23:43 +0300 Subject: [PATCH 06/20] ASoC: SOF: ipc4-pcm: Continue the pipeline trigger in case of IPC timeout Ignore IPC errors for pipeline state change if the firmware state is crashed or the IPC has timed out. If the firmware has crashed the kernel still needs to go through the state changes to reset its internal to be able to correctly work the next time the DSP is booted up. The case with IPC timeout is a bit more problematic, but it has been rootcaused to be the result of system scheduling blockage and the firmware did actually received and handled the message, but the reply handling got blocked by issues outside of the SOF stack. So far the best way to handle this is to continue with setting the state. Fixes: c40aad7c81e5 ("ASoC: SOF: ipc4-pcm: Workaround for crashed firmware on system suspend") Cc: stable@vger.kernel.org Signed-off-by: Peter Ujfalusi Reviewed-by: Kai Vehmanen Link: https://patch.msgid.link/20260730112343.26687-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-pcm.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index fc3ead77e5ea..5929ecf6642e 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -528,7 +528,19 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, ret = sof_ipc4_set_multi_pipeline_state(sdev, SOF_IPC4_PIPE_PAUSED, trigger_list); if (ret < 0) { spcm_err(spcm, substream->stream, "failed to pause all pipelines\n"); - goto free; + /* + * workaround: if the firmware is crashed or the IPC timed out + * while setting the pipeline state we must ignore the error + * code and proceed to set adjust the local pipeline states. + * + * If the firmware is crashed we will not send IPC messages + * and we are going to see errors printed, but the state of the + * widgets will be correct for the next boot. + */ + if (sdev->fw_state != SOF_FW_CRASHED && ret != -ETIMEDOUT) + goto free; + + ret = 0; } /* update PAUSED state for all pipelines just triggered */ @@ -560,14 +572,15 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, "failed to set final state %d for all pipelines\n", state); /* - * workaround: if the firmware is crashed while setting the - * pipelines to reset state we must ignore the error code and - * reset it to 0. - * Since the firmware is crashed we will not send IPC messages + * workaround: if the firmware is crashed or the IPC timed out + * while setting the pipeline state we must ignore the error + * code and proceed to set adjust the local pipeline states. + * + * If the firmware is crashed we will not send IPC messages * and we are going to see errors printed, but the state of the * widgets will be correct for the next boot. */ - if (sdev->fw_state != SOF_FW_CRASHED || state != SOF_IPC4_PIPE_RESET) + if (sdev->fw_state != SOF_FW_CRASHED && ret != -ETIMEDOUT) goto free; ret = 0; From 1ba381759e45d5d0442452cfa5c42e836191a568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Wro=CC=81bel?= Date: Thu, 30 Jul 2026 12:58:12 +0200 Subject: [PATCH 07/20] ASoC: codecs: lpass-tx-macro: Fix enum kcontrol accesses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "DEC0 MODE" to "DEC7 MODE" controls are enumerated, but tx_macro_dec_mode_get() and tx_macro_dec_mode_put() access their value through ucontrol->value.integer.value[0] (a long) instead of ucontrol->value.enumerated.item[0] (an unsigned int). This same pattern was fixed in the sibling drivers by commit bcfe5f76cc40 ("ASoC: codecs: rx-macro: fix accessing array out of bounds for enum type") and commit 0ea5eff7c606 ("ASoC: codecs: va-macro: fix accessing array out of bounds for enum type"), but tx-macro was missed. On 64-bit kernels built with CONFIG_SND_CTL_DEBUG, the elem value sanity check catches the 4 bytes written past the enumerated item and every read of these controls fails with -EINVAL: snd-sm8250 sound: control 2:0:0:DEC0 MODE:0: access overflow Fixes: c39667ddcfc5 ("ASoC: codecs: lpass-tx-macro: add support for lpass tx macro") Assisted-by: Claude:claude-fable-5 Cc: stable@vger.kernel.org Signed-off-by: Dawid Wróbel Reviewed-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260730-worktree-lpass-tx-macro-enum-fix-v2-1-6d091c736116@dawidwrobel.com Signed-off-by: Mark Brown --- sound/soc/codecs/lpass-tx-macro.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c index f7d168f557dd..0cbf50647ff5 100644 --- a/sound/soc/codecs/lpass-tx-macro.c +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -1075,7 +1075,7 @@ static int tx_macro_dec_mode_get(struct snd_kcontrol *kcontrol, struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; int path = e->shift_l; - ucontrol->value.integer.value[0] = tx->dec_mode[path]; + ucontrol->value.enumerated.item[0] = tx->dec_mode[path]; return 0; } @@ -1084,7 +1084,7 @@ static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - int value = ucontrol->value.integer.value[0]; + int value = ucontrol->value.enumerated.item[0]; struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; int path = e->shift_l; struct tx_macro *tx = snd_soc_component_get_drvdata(component); From 56f24311fd5607588a47e44675195a9efb200f29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Wro=CC=81bel?= Date: Thu, 30 Jul 2026 12:58:13 +0200 Subject: [PATCH 08/20] ASoC: codecs: lpass-wsa-macro: Fix enum kcontrol accesses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EAR SPKR PA Gain" and the four "WSA RX* Mux" controls are enumerated, but their get and put callbacks access the value through ucontrol->value.integer.value[0] (a long) instead of ucontrol->value.enumerated.item[0] (an unsigned int). This same pattern was fixed in the sibling drivers by commit bcfe5f76cc40 ("ASoC: codecs: rx-macro: fix accessing array out of bounds for enum type") and commit 0ea5eff7c606 ("ASoC: codecs: va-macro: fix accessing array out of bounds for enum type"), but wsa-macro was missed. On 64-bit kernels with CONFIG_SND_CTL_DEBUG this trips the elem value sanity check and every read of these controls fails with -EINVAL. Fixes: 809bcbcecebf ("ASoC: codecs: lpass-wsa-macro: Add support to WSA Macro") Fixes: 2c4066e5d428 ("ASoC: codecs: lpass-wsa-macro: add dapm widgets and route") Assisted-by: Claude:claude-fable-5 Cc: stable@vger.kernel.org Signed-off-by: Dawid Wróbel Reviewed-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260730-worktree-lpass-tx-macro-enum-fix-v2-2-6d091c736116@dawidwrobel.com Signed-off-by: Mark Brown --- sound/soc/codecs/lpass-wsa-macro.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c index 5ad0448af649..af521e0988db 100644 --- a/sound/soc/codecs/lpass-wsa-macro.c +++ b/sound/soc/codecs/lpass-wsa-macro.c @@ -2064,7 +2064,7 @@ static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); - ucontrol->value.integer.value[0] = wsa->ear_spkr_gain; + ucontrol->value.enumerated.item[0] = wsa->ear_spkr_gain; return 0; } @@ -2075,7 +2075,7 @@ static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); - wsa->ear_spkr_gain = ucontrol->value.integer.value[0]; + wsa->ear_spkr_gain = ucontrol->value.enumerated.item[0]; return 0; } @@ -2088,7 +2088,7 @@ static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol, snd_soc_dapm_to_component(widget->dapm); struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); - ucontrol->value.integer.value[0] = + ucontrol->value.enumerated.item[0] = wsa->rx_port_value[widget->shift]; return 0; } @@ -2101,7 +2101,7 @@ static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol, snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct snd_soc_dapm_update *update = NULL; - u32 rx_port_value = ucontrol->value.integer.value[0]; + u32 rx_port_value = ucontrol->value.enumerated.item[0]; u32 bit_input; u32 aif_rst; unsigned int dai_id; From 23b64e9b9ba2feb1884386042ddbc4872aeab31b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 23 Jul 2026 06:34:20 +0000 Subject: [PATCH 09/20] ASoC: soc-component: move soc_component_field_shift() soc_component_field_shift() is used from snd_soc_component_{read/write}_field(). It is better to located around them. Signed-off-by: Kuninori Morimoto Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/87wlumrz83.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-component.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c index 2ce24513fac5..7fbd6a711ed8 100644 --- a/sound/soc/soc-component.c +++ b/sound/soc/soc-component.c @@ -29,18 +29,6 @@ static inline int _soc_component_ret_reg_rw(struct snd_soc_component *component, func, component->name, reg); } -static inline int soc_component_field_shift(struct snd_soc_component *component, - unsigned int mask) -{ - if (!mask) { - dev_err(component->dev, "ASoC: error field mask is zero for %s\n", - component->name); - return 0; - } - - return (ffs(mask) - 1); -} - /* * We might want to check substream by using list. * In such case, we can update these macros. @@ -820,6 +808,18 @@ int snd_soc_component_update_bits_async(struct snd_soc_component *component, } EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async); +static inline int soc_component_field_shift(struct snd_soc_component *component, + unsigned int mask) +{ + if (!mask) { + dev_err(component->dev, "ASoC: error field mask is zero for %s\n", + component->name); + return 0; + } + + return (ffs(mask) - 1); +} + /** * snd_soc_component_read_field() - Read register field value * @component: Component to read from From de182d84b3a73f93fbd524843bcf6987bae76120 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 23 Jul 2026 06:34:24 +0000 Subject: [PATCH 10/20] ASoC: soc-component: add snd_soc_component_alloc() struct snd_soc_component will be capsuled soon, then, we will can't alloc it. Adds snd_soc_component_alloc() to alloc it. Signed-off-by: Kuninori Morimoto Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/87v7a6rz80.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc-component.h | 1 + sound/soc/soc-component.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h index 4b7d7954953d..874559458bd5 100644 --- a/include/sound/soc-component.h +++ b/include/sound/soc-component.h @@ -283,6 +283,7 @@ static inline int snd_soc_component_cache_sync( return regcache_sync(component->regmap); } +struct snd_soc_component *snd_soc_component_alloc(struct device *dev); void snd_soc_component_set_aux(struct snd_soc_component *component, struct snd_soc_aux_dev *aux); int snd_soc_component_init(struct snd_soc_component *component); diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c index 7fbd6a711ed8..60531e9f9f9a 100644 --- a/sound/soc/soc-component.c +++ b/sound/soc/soc-component.c @@ -29,6 +29,19 @@ static inline int _soc_component_ret_reg_rw(struct snd_soc_component *component, func, component->name, reg); } +struct snd_soc_component *snd_soc_component_alloc(struct device *dev) +{ + struct snd_soc_component *component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL); + + if (!component) + return NULL; + + component->dev = dev; + + return component; +} +EXPORT_SYMBOL_GPL(snd_soc_component_alloc); + /* * We might want to check substream by using list. * In such case, we can update these macros. From 3e53dc96a007a40ee9a8b24e5884aa216381964a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 23 Jul 2026 06:34:27 +0000 Subject: [PATCH 11/20] ASoC: soc-component: add snd_soc_register_component_{c/d}() We have snd_soc_register_component() (A), but we can't setup component specific setting, like name, etc from driver, because component itself is allocated in that function (x). (A) int snd_soc_register_component(...) { ... (x) component = devm_kzalloc(...); if (!component) return -ENOMEM; (B) ret = snd_soc_component_initialize(...); if (ret < 0) return ret; (C) return snd_soc_add_component(...); } So each driver needs to use snd_soc_component_{initialize/add}() (= B/C) instead of using snd_soc_register_component() (A), but it looks unbalanced with its paired unregiser function. Let's merge (B) and (C) into new register function, and allows component as parameter. We can use both snd_soc_register_component(dev, ...); // already exists snd_soc_register_component(component, ...); // new function Signed-off-by: Kuninori Morimoto Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/87tspqrz7w.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc.h | 9 ++++++++- sound/soc/soc-core.c | 26 ++++++++++++++++++-------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 10ad80f930c2..cb0de41e2ada 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -453,9 +453,16 @@ int snd_soc_component_initialize(struct snd_soc_component *component, int snd_soc_add_component(struct snd_soc_component *component, struct snd_soc_dai_driver *dai_drv, int num_dai); -int snd_soc_register_component(struct device *dev, +int snd_soc_register_component_c(struct snd_soc_component *component, const struct snd_soc_component_driver *component_driver, struct snd_soc_dai_driver *dai_drv, int num_dai); +int snd_soc_register_component_d(struct device *dev, + const struct snd_soc_component_driver *component_driver, + struct snd_soc_dai_driver *dai_drv, int num_dai); +#define snd_soc_register_component(x, ...) _Generic((x), \ +struct device * : snd_soc_register_component_d, \ +struct snd_soc_component * : snd_soc_register_component_c)(x, __VA_ARGS__) + int devm_snd_soc_register_component(struct device *dev, const struct snd_soc_component_driver *component_driver, struct snd_soc_dai_driver *dai_drv, int num_dai); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 44f9bb4473f5..c4c99944d4b6 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2780,25 +2780,35 @@ int snd_soc_add_component(struct snd_soc_component *component, } EXPORT_SYMBOL_GPL(snd_soc_add_component); -int snd_soc_register_component(struct device *dev, +int snd_soc_register_component_c(struct snd_soc_component *component, const struct snd_soc_component_driver *component_driver, struct snd_soc_dai_driver *dai_drv, int num_dai) { - struct snd_soc_component *component; int ret; - component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL); - if (!component) - return -ENOMEM; - - ret = snd_soc_component_initialize(component, component_driver, dev); + ret = snd_soc_component_initialize(component, component_driver, component->dev); if (ret < 0) return ret; return snd_soc_add_component(component, dai_drv, num_dai); } -EXPORT_SYMBOL_GPL(snd_soc_register_component); +EXPORT_SYMBOL_GPL(snd_soc_register_component_c); + +int snd_soc_register_component_d(struct device *dev, + const struct snd_soc_component_driver *component_driver, + struct snd_soc_dai_driver *dai_drv, + int num_dai) +{ + struct snd_soc_component *component; + + component = snd_soc_component_alloc(dev); + if (!component) + return -ENOMEM; + + return snd_soc_register_component_c(component, component_driver, dai_drv, num_dai); +} +EXPORT_SYMBOL_GPL(snd_soc_register_component_d); /** * snd_soc_unregister_component_by_driver - Unregister component using a given driver From f6cfdd246c256f3f87f50254cd6e105c7568ae57 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 23 Jul 2026 06:34:31 +0000 Subject: [PATCH 12/20] ASoC: soc-component: add snd_soc_component_{set_}name() struct snd_soc_component will be capsuled soon, its member will not be able to access from non soc-component.c. Add snd_soc_component_{set_}name() to access name. Signed-off-by: Kuninori Morimoto Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/87se5arz7s.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc-component.h | 4 ++++ sound/soc/soc-component.c | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h index 874559458bd5..a13d5c98e0f3 100644 --- a/include/sound/soc-component.h +++ b/include/sound/soc-component.h @@ -284,6 +284,10 @@ static inline int snd_soc_component_cache_sync( } struct snd_soc_component *snd_soc_component_alloc(struct device *dev); + +void snd_soc_component_set_name(struct snd_soc_component *component, const char *name); +const char *snd_soc_component_name(struct snd_soc_component *component); + void snd_soc_component_set_aux(struct snd_soc_component *component, struct snd_soc_aux_dev *aux); int snd_soc_component_init(struct snd_soc_component *component); diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c index 60531e9f9f9a..5131e2bf3a10 100644 --- a/sound/soc/soc-component.c +++ b/sound/soc/soc-component.c @@ -42,6 +42,18 @@ struct snd_soc_component *snd_soc_component_alloc(struct device *dev) } EXPORT_SYMBOL_GPL(snd_soc_component_alloc); +void snd_soc_component_set_name(struct snd_soc_component *component, const char *name) +{ + component->name = name; +} +EXPORT_SYMBOL_GPL(snd_soc_component_set_name); + +const char *snd_soc_component_name(struct snd_soc_component *component) +{ + return component->name; +} +EXPORT_SYMBOL_GPL(snd_soc_component_name); + /* * We might want to check substream by using list. * In such case, we can update these macros. From d99690513a9aff85ad282e5d622844b66471319c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 23 Jul 2026 06:34:35 +0000 Subject: [PATCH 13/20] ASoC: soc-component: add snd_soc_component_{set/to}_priv() struct snd_soc_component will be capsuled soon, its member will not be able to access from non soc-component.c. Basically, each drivers are using dev_{set/get}_drvdata() to set own data, but it is not enough. Let's add .priv. Add snd_soc_component_{set/to}_priv() to access priv. Signed-off-by: Kuninori Morimoto Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/87qzkurz7o.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc-component.h | 6 ++++++ sound/soc/soc-component.c | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h index a13d5c98e0f3..c49b59630101 100644 --- a/include/sound/soc-component.h +++ b/include/sound/soc-component.h @@ -253,6 +253,9 @@ struct snd_soc_component { void *mark_pm; struct dentry *debugfs_root; + + /* Component private data */ + void *priv; }; #define for_each_component_dais(component, dai)\ @@ -288,6 +291,9 @@ struct snd_soc_component *snd_soc_component_alloc(struct device *dev); void snd_soc_component_set_name(struct snd_soc_component *component, const char *name); const char *snd_soc_component_name(struct snd_soc_component *component); +void snd_soc_component_set_priv(struct snd_soc_component *component, void *priv); +void *snd_soc_component_to_priv(struct snd_soc_component *component); + void snd_soc_component_set_aux(struct snd_soc_component *component, struct snd_soc_aux_dev *aux); int snd_soc_component_init(struct snd_soc_component *component); diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c index 5131e2bf3a10..dc7d203cb76a 100644 --- a/sound/soc/soc-component.c +++ b/sound/soc/soc-component.c @@ -54,6 +54,18 @@ const char *snd_soc_component_name(struct snd_soc_component *component) } EXPORT_SYMBOL_GPL(snd_soc_component_name); +void snd_soc_component_set_priv(struct snd_soc_component *component, void *priv) +{ + component->priv = priv; +} +EXPORT_SYMBOL_GPL(snd_soc_component_set_priv); + +void *snd_soc_component_to_priv(struct snd_soc_component *component) +{ + return component->priv; +} +EXPORT_SYMBOL_GPL(snd_soc_component_to_priv); + /* * We might want to check substream by using list. * In such case, we can update these macros. From 6105b0c10c57ce93c2a407522c4dbe0885a94253 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 23 Jul 2026 06:34:39 +0000 Subject: [PATCH 14/20] ASoC: intel: avs: use snd_soc_register_component() It is calling snd_soc_component_initialize() / snd_soc_add_component(). We can now use snd_soc_register_component() instead. It is using container_of() to get avs_soc_component from component, but will not be able to use it when capsuling has done. We can now use snd_soc_component_to_priv() instead. Signed-off-by: Kuninori Morimoto Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/87pl0erz7k.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/avs.h | 5 ++--- sound/soc/intel/avs/ipc.c | 2 +- sound/soc/intel/avs/pcm.c | 19 +++++++++++-------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index 0f8ddd0e9e5f..b4f9d66d55ad 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -336,14 +336,13 @@ int avs_icl_load_basefw(struct avs_dev *adev, struct firmware *fw); /* Soc component members */ struct avs_soc_component { - struct snd_soc_component base; + struct snd_soc_component *base; struct avs_tplg *tplg; struct list_head node; }; -#define to_avs_soc_component(comp) \ - container_of(comp, struct avs_soc_component, base) +#define to_avs_soc_component(comp) snd_soc_component_to_priv(comp) extern const struct snd_soc_dai_ops avs_dai_fe_ops; diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c index 71e7997e52c2..39b0de9831da 100644 --- a/sound/soc/intel/avs/ipc.c +++ b/sound/soc/intel/avs/ipc.c @@ -106,7 +106,7 @@ static void avs_dsp_recovery(struct avs_dev *adev) struct snd_soc_pcm_runtime *rtd; struct snd_soc_card *card; - card = acomp->base.card; + card = acomp->base->card; if (!card) continue; diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 797b9c9163b4..2b886fae8209 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -958,7 +958,7 @@ static const struct file_operations topology_name_fops = { static int avs_component_load_libraries(struct avs_soc_component *acomp) { struct avs_tplg *tplg = acomp->tplg; - struct avs_dev *adev = to_avs_dev(acomp->base.dev); + struct avs_dev *adev = to_avs_dev(acomp->base->dev); int ret; if (!tplg->num_libs) @@ -1387,25 +1387,28 @@ int avs_register_component(struct device *dev, const char *name, struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais) { struct avs_soc_component *acomp; - int ret; + const char *comp_name; acomp = devm_kzalloc(dev, sizeof(*acomp), GFP_KERNEL); if (!acomp) return -ENOMEM; - acomp->base.name = devm_kstrdup(dev, name, GFP_KERNEL); - if (!acomp->base.name) + acomp->base = snd_soc_component_alloc(dev); + if (!acomp->base) + return -ENOMEM; + + comp_name = devm_kstrdup(dev, name, GFP_KERNEL); + if (!comp_name) return -ENOMEM; INIT_LIST_HEAD(&acomp->node); drv->use_dai_pcm_id = !obsolete_card_names; - ret = snd_soc_component_initialize(&acomp->base, drv, dev); - if (ret < 0) - return ret; + snd_soc_component_set_name(acomp->base, comp_name); + snd_soc_component_set_priv(acomp->base, acomp); - return snd_soc_add_component(&acomp->base, cpu_dais, num_cpu_dais); + return snd_soc_register_component(acomp->base, drv, cpu_dais, num_cpu_dais); } static struct snd_soc_dai_driver dmic_cpu_dais[] = { From 82552166455946c95d87fe813789cdd9689008e8 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 23 Jul 2026 06:34:43 +0000 Subject: [PATCH 15/20] ASoC: intel: avs: probes: use snd_soc_register_component() It is calling snd_soc_component_initialize() / snd_soc_add_component(). We can now use snd_soc_register_component() instead. Signed-off-by: Kuninori Morimoto Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/87o6fyrz7h.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/probes.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/intel/avs/probes.c b/sound/soc/intel/avs/probes.c index 099119ad28b3..e957ef46198a 100644 --- a/sound/soc/intel/avs/probes.c +++ b/sound/soc/intel/avs/probes.c @@ -296,19 +296,19 @@ static const struct snd_soc_component_driver avs_probe_component_driver = { int avs_register_probe_component(struct avs_dev *adev, const char *name) { struct snd_soc_component *component; - int ret; + const char *comp_name; - component = devm_kzalloc(adev->dev, sizeof(*component), GFP_KERNEL); + component = snd_soc_component_alloc(adev->dev); if (!component) return -ENOMEM; - component->name = devm_kstrdup(adev->dev, name, GFP_KERNEL); - if (!component->name) + comp_name = devm_kstrdup(adev->dev, name, GFP_KERNEL); + if (!comp_name) return -ENOMEM; - ret = snd_soc_component_initialize(component, &avs_probe_component_driver, adev->dev); - if (ret) - return ret; + snd_soc_component_set_name(component, comp_name); - return snd_soc_add_component(component, probe_cpu_dais, ARRAY_SIZE(probe_cpu_dais)); + return snd_soc_register_component(component, + &avs_probe_component_driver, + probe_cpu_dais, ARRAY_SIZE(probe_cpu_dais)); } From c8eaeedcace341eedc712f97aeee3aeb0c9b9f47 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 23 Jul 2026 06:34:46 +0000 Subject: [PATCH 16/20] ASoC: intel: catpt: pcm: use snd_soc_register_component() It is calling snd_soc_component_initialize() / snd_soc_add_component(). We can now use snd_soc_register_component() instead. Signed-off-by: Kuninori Morimoto Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/87mrvirz7d.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/intel/catpt/pcm.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c index f23c580ba051..bbba0d959ea2 100644 --- a/sound/soc/intel/catpt/pcm.c +++ b/sound/soc/intel/catpt/pcm.c @@ -1072,18 +1072,14 @@ int catpt_arm_stream_templates(struct catpt_dev *cdev) int catpt_register_plat_component(struct catpt_dev *cdev) { struct snd_soc_component *component; - int ret; - component = devm_kzalloc(cdev->dev, sizeof(*component), GFP_KERNEL); + component = snd_soc_component_alloc(cdev->dev); if (!component) return -ENOMEM; - ret = snd_soc_component_initialize(component, &catpt_comp_driver, - cdev->dev); - if (ret) - return ret; + snd_soc_component_set_name(component, catpt_comp_driver.name); - component->name = catpt_comp_driver.name; - return snd_soc_add_component(component, dai_drivers, - ARRAY_SIZE(dai_drivers)); + return snd_soc_register_component(component, + &catpt_comp_driver, + dai_drivers, ARRAY_SIZE(dai_drivers)); } From 695cc675f0d587822ffed64e46680beaa6541fc2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 23 Jul 2026 06:34:50 +0000 Subject: [PATCH 17/20] ASoC: soc-generic-dmaengine-pcm: use snd_soc_register_component() it is calling snd_soc_component_initialize() / snd_soc_add_component(). We can now use snd_soc_register_component() instead. It is using container_of() to get dmaengine_pcm from component, but will not be able to use it when capsuling has done. We can now use snd_soc_component_to_priv() instead. Signed-off-by: Kuninori Morimoto Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/87ldb2rz79.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/dmaengine_pcm.h | 6 ------ sound/soc/fsl/fsl_asrc_dma.c | 4 +++- sound/soc/soc-generic-dmaengine-pcm.c | 30 ++++++++++++++------------- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index 9472f0a966a2..81422219ed39 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -175,12 +175,6 @@ int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream, struct dmaengine_pcm { struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1]; const struct snd_dmaengine_pcm_config *config; - struct snd_soc_component component; unsigned int flags; }; - -static inline struct dmaengine_pcm *soc_component_to_pcm(struct snd_soc_component *p) -{ - return container_of(p, struct dmaengine_pcm, component); -} #endif diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c index 38f2b7c63133..2f662bdf14d0 100644 --- a/sound/soc/fsl/fsl_asrc_dma.c +++ b/sound/soc/fsl/fsl_asrc_dma.c @@ -219,7 +219,9 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, */ component_be = snd_soc_lookup_component_nolocked(dev_be, SND_DMAENGINE_PCM_DRV_NAME); if (component_be) { - be_chan = soc_component_to_pcm(component_be)->chan[substream->stream]; + struct dmaengine_pcm *pcm = snd_soc_component_to_priv(component_be); + + be_chan = pcm->chan[substream->stream]; tmp_chan = be_chan; } if (!tmp_chan) { diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index 98ba9a836936..3b18d90e81c3 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c @@ -78,7 +78,7 @@ static int dmaengine_pcm_hw_params(struct snd_soc_component *component, struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct dmaengine_pcm *pcm = soc_component_to_pcm(component); + struct dmaengine_pcm *pcm = snd_soc_component_to_priv(component); struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); struct dma_slave_config slave_config; int ret; @@ -100,7 +100,7 @@ dmaengine_pcm_set_runtime_hwparams(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); - struct dmaengine_pcm *pcm = soc_component_to_pcm(component); + struct dmaengine_pcm *pcm = snd_soc_component_to_priv(component); struct device *dma_dev = dmaengine_dma_dev(pcm, substream); struct dma_chan *chan = pcm->chan[substream->stream]; struct snd_dmaengine_dai_dma_data *dma_data; @@ -149,7 +149,7 @@ dmaengine_pcm_set_runtime_hwparams(struct snd_soc_component *component, static int dmaengine_pcm_open(struct snd_soc_component *component, struct snd_pcm_substream *substream) { - struct dmaengine_pcm *pcm = soc_component_to_pcm(component); + struct dmaengine_pcm *pcm = snd_soc_component_to_priv(component); struct dma_chan *chan = pcm->chan[substream->stream]; int ret; @@ -177,7 +177,7 @@ static struct dma_chan *dmaengine_pcm_compat_request_channel( struct snd_soc_pcm_runtime *rtd, struct snd_pcm_substream *substream) { - struct dmaengine_pcm *pcm = soc_component_to_pcm(component); + struct dmaengine_pcm *pcm = snd_soc_component_to_priv(component); struct snd_dmaengine_dai_dma_data *dma_data; if (rtd->dai_link->num_cpus > 1) { @@ -220,7 +220,7 @@ static bool dmaengine_pcm_can_report_residue(struct device *dev, static int dmaengine_pcm_new(struct snd_soc_component *component, struct snd_soc_pcm_runtime *rtd) { - struct dmaengine_pcm *pcm = soc_component_to_pcm(component); + struct dmaengine_pcm *pcm = snd_soc_component_to_priv(component); const struct snd_dmaengine_pcm_config *config = pcm->config; struct device *dev = component->dev; size_t prealloc_buffer_size; @@ -280,7 +280,7 @@ static snd_pcm_uframes_t dmaengine_pcm_pointer( struct snd_soc_component *component, struct snd_pcm_substream *substream) { - struct dmaengine_pcm *pcm = soc_component_to_pcm(component); + struct dmaengine_pcm *pcm = snd_soc_component_to_priv(component); if (pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) return snd_dmaengine_pcm_pointer_no_residue(substream); @@ -294,7 +294,7 @@ static int dmaengine_copy(struct snd_soc_component *component, struct iov_iter *iter, unsigned long bytes) { struct snd_pcm_runtime *runtime = substream->runtime; - struct dmaengine_pcm *pcm = soc_component_to_pcm(component); + struct dmaengine_pcm *pcm = snd_soc_component_to_priv(component); int (*process)(struct snd_pcm_substream *substream, int channel, unsigned long hwoff, unsigned long bytes) = pcm->config->process; @@ -463,10 +463,15 @@ static const struct snd_dmaengine_pcm_config snd_dmaengine_pcm_default_config = int snd_dmaengine_pcm_register(struct device *dev, const struct snd_dmaengine_pcm_config *config, unsigned int flags) { + struct snd_soc_component *component; const struct snd_soc_component_driver *driver; struct dmaengine_pcm *pcm; int ret; + component = snd_soc_component_alloc(dev); + if (!component) + return -ENOMEM; + pcm = kzalloc_obj(*pcm); if (!pcm) return -ENOMEM; @@ -477,7 +482,8 @@ int snd_dmaengine_pcm_register(struct device *dev, pcm->flags = flags; if (config->name) - pcm->component.name = config->name; + snd_soc_component_set_name(component, config->name); + snd_soc_component_set_priv(component, pcm); ret = dmaengine_pcm_request_chan_of(pcm, dev, config); if (ret) @@ -488,11 +494,7 @@ int snd_dmaengine_pcm_register(struct device *dev, else driver = &dmaengine_pcm_component; - ret = snd_soc_component_initialize(&pcm->component, driver, dev); - if (ret) - goto err_free_dma; - - ret = snd_soc_add_component(&pcm->component, NULL, 0); + ret = snd_soc_register_component(component, driver, NULL, 0); if (ret) goto err_free_dma; @@ -521,7 +523,7 @@ void snd_dmaengine_pcm_unregister(struct device *dev) if (!component) return; - pcm = soc_component_to_pcm(component); + pcm = snd_soc_component_to_priv(component); snd_soc_unregister_component_by_driver(dev, component->driver); dmaengine_pcm_release_chan(pcm); From 10c062304d2d13c5f8012ce82845b88cfd5fb815 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 23 Jul 2026 06:34:53 +0000 Subject: [PATCH 18/20] ASoC: soc-topology-test: use snd_soc_register_component() It is calling snd_soc_component_initialize() / snd_soc_add_component(). We can now use snd_soc_register_component() instead. It is using container_of() to get kunit_soc_component from component, but will not be able to use it when capsuling has done. We can use snd_soc_component_to_priv() instead. Signed-off-by: Kuninori Morimoto Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/87jyqmrz76.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-topology-test.c | 133 +++++++++++++++++++++------------- 1 file changed, 81 insertions(+), 52 deletions(-) diff --git a/sound/soc/soc-topology-test.c b/sound/soc/soc-topology-test.c index c8f2ec29e970..346a52d3006a 100644 --- a/sound/soc/soc-topology-test.c +++ b/sound/soc/soc-topology-test.c @@ -45,15 +45,13 @@ static void snd_soc_tplg_test_exit(struct kunit *test) struct kunit_soc_component { struct kunit *kunit; int expect; /* what result we expect when loading topology */ - struct snd_soc_component comp; struct snd_soc_card card; struct firmware fw; }; static int d_probe(struct snd_soc_component *component) { - struct kunit_soc_component *kunit_comp = - container_of(component, struct kunit_soc_component, comp); + struct kunit_soc_component *kunit_comp = snd_soc_component_to_priv(component); int ret; ret = snd_soc_tplg_component_load(component, NULL, &kunit_comp->fw); @@ -65,8 +63,7 @@ static int d_probe(struct snd_soc_component *component) static void d_remove(struct snd_soc_component *component) { - struct kunit_soc_component *kunit_comp = - container_of(component, struct kunit_soc_component, comp); + struct kunit_soc_component *kunit_comp = snd_soc_component_to_priv(component); int ret; ret = snd_soc_tplg_component_remove(component); @@ -214,8 +211,7 @@ static struct tplg_tmpl_002 tplg_tmpl_with_pcm = { */ static int d_probe_null_comp(struct snd_soc_component *component) { - struct kunit_soc_component *kunit_comp = - container_of(component, struct kunit_soc_component, comp); + struct kunit_soc_component *kunit_comp = snd_soc_component_to_priv(component); int ret; /* instead of passing component pointer as first argument, pass NULL here */ @@ -234,6 +230,7 @@ static const struct snd_soc_component_driver test_component_null_comp = { static void snd_soc_tplg_test_load_with_null_comp(struct kunit *test) { struct kunit_soc_component *kunit_comp; + struct snd_soc_component *component; int ret; /* prepare */ @@ -249,15 +246,17 @@ static void snd_soc_tplg_test_load_with_null_comp(struct kunit *test) kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links); kunit_comp->card.fully_routed = true; + component = snd_soc_component_alloc(test_dev); + KUNIT_ASSERT_NOT_NULL(test, component); + + snd_soc_component_set_priv(component, kunit_comp); + /* run test */ ret = snd_soc_register_card(&kunit_comp->card); if (ret != 0 && ret != -EPROBE_DEFER) KUNIT_FAIL(test, "Failed to register card"); - ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component_null_comp, test_dev); - KUNIT_EXPECT_EQ(test, 0, ret); - - ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + ret = snd_soc_register_component(component, &test_component_null_comp, NULL, 0); KUNIT_EXPECT_EQ(test, 0, ret); /* cleanup */ @@ -276,6 +275,7 @@ static void snd_soc_tplg_test_load_with_null_comp(struct kunit *test) static void snd_soc_tplg_test_load_with_null_ops(struct kunit *test) { struct kunit_soc_component *kunit_comp; + struct snd_soc_component *component; int ret; /* prepare */ @@ -291,15 +291,17 @@ static void snd_soc_tplg_test_load_with_null_ops(struct kunit *test) kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links); kunit_comp->card.fully_routed = true; + component = snd_soc_component_alloc(test_dev); + KUNIT_ASSERT_NOT_NULL(test, component); + + snd_soc_component_set_priv(component, kunit_comp); + /* run test */ ret = snd_soc_register_card(&kunit_comp->card); if (ret != 0 && ret != -EPROBE_DEFER) KUNIT_FAIL(test, "Failed to register card"); - ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); - KUNIT_EXPECT_EQ(test, 0, ret); - - ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + ret = snd_soc_register_component(component, &test_component, NULL, 0); KUNIT_EXPECT_EQ(test, 0, ret); /* cleanup */ @@ -318,8 +320,7 @@ static void snd_soc_tplg_test_load_with_null_ops(struct kunit *test) */ static int d_probe_null_fw(struct snd_soc_component *component) { - struct kunit_soc_component *kunit_comp = - container_of(component, struct kunit_soc_component, comp); + struct kunit_soc_component *kunit_comp = snd_soc_component_to_priv(component); int ret; /* instead of passing fw pointer as third argument, pass NULL here */ @@ -338,6 +339,7 @@ static const struct snd_soc_component_driver test_component_null_fw = { static void snd_soc_tplg_test_load_with_null_fw(struct kunit *test) { struct kunit_soc_component *kunit_comp; + struct snd_soc_component *component; int ret; /* prepare */ @@ -353,15 +355,17 @@ static void snd_soc_tplg_test_load_with_null_fw(struct kunit *test) kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links); kunit_comp->card.fully_routed = true; + component = snd_soc_component_alloc(test_dev); + KUNIT_ASSERT_NOT_NULL(test, component); + + snd_soc_component_set_priv(component, kunit_comp); + /* run test */ ret = snd_soc_register_card(&kunit_comp->card); if (ret != 0 && ret != -EPROBE_DEFER) KUNIT_FAIL(test, "Failed to register card"); - ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component_null_fw, test_dev); - KUNIT_EXPECT_EQ(test, 0, ret); - - ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + ret = snd_soc_register_component(component, &test_component_null_fw, NULL, 0); KUNIT_EXPECT_EQ(test, 0, ret); /* cleanup */ @@ -375,6 +379,7 @@ static void snd_soc_tplg_test_load_with_null_fw(struct kunit *test) static void snd_soc_tplg_test_load_empty_tplg(struct kunit *test) { struct kunit_soc_component *kunit_comp; + struct snd_soc_component *component; struct tplg_tmpl_001 *data; int size; int ret; @@ -401,15 +406,17 @@ static void snd_soc_tplg_test_load_empty_tplg(struct kunit *test) kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links); kunit_comp->card.fully_routed = true; + component = snd_soc_component_alloc(test_dev); + KUNIT_ASSERT_NOT_NULL(test, component); + + snd_soc_component_set_priv(component, kunit_comp); + /* run test */ ret = snd_soc_register_card(&kunit_comp->card); if (ret != 0 && ret != -EPROBE_DEFER) KUNIT_FAIL(test, "Failed to register card"); - ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); - KUNIT_EXPECT_EQ(test, 0, ret); - - ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + ret = snd_soc_register_component(component, &test_component, NULL, 0); KUNIT_EXPECT_EQ(test, 0, ret); /* cleanup */ @@ -425,6 +432,7 @@ static void snd_soc_tplg_test_load_empty_tplg(struct kunit *test) static void snd_soc_tplg_test_load_empty_tplg_bad_magic(struct kunit *test) { struct kunit_soc_component *kunit_comp; + struct snd_soc_component *component; struct tplg_tmpl_001 *data; int size; int ret; @@ -456,15 +464,17 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_magic(struct kunit *test) kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links); kunit_comp->card.fully_routed = true; + component = snd_soc_component_alloc(test_dev); + KUNIT_ASSERT_NOT_NULL(test, component); + + snd_soc_component_set_priv(component, kunit_comp); + /* run test */ ret = snd_soc_register_card(&kunit_comp->card); if (ret != 0 && ret != -EPROBE_DEFER) KUNIT_FAIL(test, "Failed to register card"); - ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); - KUNIT_EXPECT_EQ(test, 0, ret); - - ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + ret = snd_soc_register_component(component, &test_component, NULL, 0); KUNIT_EXPECT_EQ(test, 0, ret); /* cleanup */ @@ -480,6 +490,7 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_magic(struct kunit *test) static void snd_soc_tplg_test_load_empty_tplg_bad_abi(struct kunit *test) { struct kunit_soc_component *kunit_comp; + struct snd_soc_component *component; struct tplg_tmpl_001 *data; int size; int ret; @@ -511,15 +522,17 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_abi(struct kunit *test) kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links); kunit_comp->card.fully_routed = true; + component = snd_soc_component_alloc(test_dev); + KUNIT_ASSERT_NOT_NULL(test, component); + + snd_soc_component_set_priv(component, kunit_comp); + /* run test */ ret = snd_soc_register_card(&kunit_comp->card); if (ret != 0 && ret != -EPROBE_DEFER) KUNIT_FAIL(test, "Failed to register card"); - ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); - KUNIT_EXPECT_EQ(test, 0, ret); - - ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + ret = snd_soc_register_component(component, &test_component, NULL, 0); KUNIT_EXPECT_EQ(test, 0, ret); /* cleanup */ @@ -535,6 +548,7 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_abi(struct kunit *test) static void snd_soc_tplg_test_load_empty_tplg_bad_size(struct kunit *test) { struct kunit_soc_component *kunit_comp; + struct snd_soc_component *component; struct tplg_tmpl_001 *data; int size; int ret; @@ -566,15 +580,17 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_size(struct kunit *test) kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links); kunit_comp->card.fully_routed = true; + component = snd_soc_component_alloc(test_dev); + KUNIT_ASSERT_NOT_NULL(test, component); + + snd_soc_component_set_priv(component, kunit_comp); + /* run test */ ret = snd_soc_register_card(&kunit_comp->card); if (ret != 0 && ret != -EPROBE_DEFER) KUNIT_FAIL(test, "Failed to register card"); - ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); - KUNIT_EXPECT_EQ(test, 0, ret); - - ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + ret = snd_soc_register_component(component, &test_component, NULL, 0); KUNIT_EXPECT_EQ(test, 0, ret); /* cleanup */ @@ -590,6 +606,7 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_size(struct kunit *test) static void snd_soc_tplg_test_load_empty_tplg_bad_payload_size(struct kunit *test) { struct kunit_soc_component *kunit_comp; + struct snd_soc_component *component; struct tplg_tmpl_001 *data; int size; int ret; @@ -622,15 +639,17 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_payload_size(struct kunit *tes kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links); kunit_comp->card.fully_routed = true; + component = snd_soc_component_alloc(test_dev); + KUNIT_ASSERT_NOT_NULL(test, component); + + snd_soc_component_set_priv(component, kunit_comp); + /* run test */ ret = snd_soc_register_card(&kunit_comp->card); if (ret != 0 && ret != -EPROBE_DEFER) KUNIT_FAIL(test, "Failed to register card"); - ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); - KUNIT_EXPECT_EQ(test, 0, ret); - - ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + ret = snd_soc_register_component(component, &test_component, NULL, 0); KUNIT_EXPECT_EQ(test, 0, ret); /* cleanup */ @@ -644,6 +663,7 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_payload_size(struct kunit *tes static void snd_soc_tplg_test_load_pcm_tplg(struct kunit *test) { struct kunit_soc_component *kunit_comp; + struct snd_soc_component *component; u8 *data; int size; int ret; @@ -670,15 +690,17 @@ static void snd_soc_tplg_test_load_pcm_tplg(struct kunit *test) kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links); kunit_comp->card.fully_routed = true; + component = snd_soc_component_alloc(test_dev); + KUNIT_ASSERT_NOT_NULL(test, component); + + snd_soc_component_set_priv(component, kunit_comp); + /* run test */ ret = snd_soc_register_card(&kunit_comp->card); if (ret != 0 && ret != -EPROBE_DEFER) KUNIT_FAIL(test, "Failed to register card"); - ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); - KUNIT_EXPECT_EQ(test, 0, ret); - - ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + ret = snd_soc_register_component(component, &test_component, NULL, 0); KUNIT_EXPECT_EQ(test, 0, ret); snd_soc_unregister_component(test_dev); @@ -693,6 +715,7 @@ static void snd_soc_tplg_test_load_pcm_tplg(struct kunit *test) static void snd_soc_tplg_test_load_pcm_tplg_reload_comp(struct kunit *test) { struct kunit_soc_component *kunit_comp; + struct snd_soc_component *component; u8 *data; int size; int ret; @@ -720,16 +743,19 @@ static void snd_soc_tplg_test_load_pcm_tplg_reload_comp(struct kunit *test) kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links); kunit_comp->card.fully_routed = true; + component = snd_soc_component_alloc(test_dev); + KUNIT_ASSERT_NOT_NULL(test, component); + + snd_soc_component_set_priv(component, kunit_comp); + /* run test */ ret = snd_soc_register_card(&kunit_comp->card); if (ret != 0 && ret != -EPROBE_DEFER) KUNIT_FAIL(test, "Failed to register card"); for (i = 0; i < 100; i++) { - ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); - KUNIT_EXPECT_EQ(test, 0, ret); - ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + ret = snd_soc_register_component(component, &test_component, NULL, 0); KUNIT_EXPECT_EQ(test, 0, ret); snd_soc_unregister_component(test_dev); @@ -745,6 +771,7 @@ static void snd_soc_tplg_test_load_pcm_tplg_reload_comp(struct kunit *test) static void snd_soc_tplg_test_load_pcm_tplg_reload_card(struct kunit *test) { struct kunit_soc_component *kunit_comp; + struct snd_soc_component *component; u8 *data; int size; int ret; @@ -772,11 +799,13 @@ static void snd_soc_tplg_test_load_pcm_tplg_reload_card(struct kunit *test) kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links); kunit_comp->card.fully_routed = true; - /* run test */ - ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev); - KUNIT_EXPECT_EQ(test, 0, ret); + component = snd_soc_component_alloc(test_dev); + KUNIT_ASSERT_NOT_NULL(test, component); - ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0); + snd_soc_component_set_priv(component, kunit_comp); + + /* run test */ + ret = snd_soc_register_component(component, &test_component, NULL, 0); KUNIT_EXPECT_EQ(test, 0, ret); for (i = 0; i < 100; i++) { From 7050ee33c2db8e96bdbcd97f49a7ffa1d9b3ce1a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 23 Jul 2026 06:34:57 +0000 Subject: [PATCH 19/20] ASoC: soc-core: makes snd_soc_component_initialize() / snd_soc_add_component() local No one is calling snd_soc_component_initialize() / snd_soc_add_component() calling from driver. Makes them local functions. It renames - snd_soc_add_component() + snd_soc_component_add() Signed-off-by: Kuninori Morimoto Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/87ik66rz73.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc.h | 6 ------ sound/soc/soc-core.c | 18 ++++++++---------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index cb0de41e2ada..f46b2bc2a022 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -447,12 +447,6 @@ static inline int snd_soc_resume(struct device *dev) } #endif int snd_soc_poweroff(struct device *dev); -int snd_soc_component_initialize(struct snd_soc_component *component, - const struct snd_soc_component_driver *driver, - struct device *dev); -int snd_soc_add_component(struct snd_soc_component *component, - struct snd_soc_dai_driver *dai_drv, - int num_dai); int snd_soc_register_component_c(struct snd_soc_component *component, const struct snd_soc_component_driver *component_driver, struct snd_soc_dai_driver *dai_drv, int num_dai); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index c4c99944d4b6..ec23ba261897 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2707,9 +2707,9 @@ static void snd_soc_del_component_unlocked(struct snd_soc_component *component) list_del(&component->list); } -int snd_soc_component_initialize(struct snd_soc_component *component, - const struct snd_soc_component_driver *driver, - struct device *dev) +static int soc_component_initialize(struct snd_soc_component *component, + const struct snd_soc_component_driver *driver, + struct device *dev) { component->dapm = snd_soc_dapm_alloc(dev); if (!component->dapm) @@ -2735,11 +2735,10 @@ int snd_soc_component_initialize(struct snd_soc_component *component, return 0; } -EXPORT_SYMBOL_GPL(snd_soc_component_initialize); -int snd_soc_add_component(struct snd_soc_component *component, - struct snd_soc_dai_driver *dai_drv, - int num_dai) +static int soc_component_add(struct snd_soc_component *component, + struct snd_soc_dai_driver *dai_drv, + int num_dai) { struct snd_soc_card *card, *c; int ret; @@ -2778,7 +2777,6 @@ int snd_soc_add_component(struct snd_soc_component *component, return ret; } -EXPORT_SYMBOL_GPL(snd_soc_add_component); int snd_soc_register_component_c(struct snd_soc_component *component, const struct snd_soc_component_driver *component_driver, @@ -2787,11 +2785,11 @@ int snd_soc_register_component_c(struct snd_soc_component *component, { int ret; - ret = snd_soc_component_initialize(component, component_driver, component->dev); + ret = soc_component_initialize(component, component_driver, component->dev); if (ret < 0) return ret; - return snd_soc_add_component(component, dai_drv, num_dai); + return soc_component_add(component, dai_drv, num_dai); } EXPORT_SYMBOL_GPL(snd_soc_register_component_c); From 157936199385fbd16d5e25152ac07a246e64a6e1 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 23 Jul 2026 06:35:01 +0000 Subject: [PATCH 20/20] ASoC: soc-core: remove dev from soc_component_initialize() Component already has component->dev. No longer need to set dev on soc_component_initialize(). Remove it. Signed-off-by: Kuninori Morimoto Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/87h5lqrz6z.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index ec23ba261897..b9c70268d49f 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2708,9 +2708,10 @@ static void snd_soc_del_component_unlocked(struct snd_soc_component *component) } static int soc_component_initialize(struct snd_soc_component *component, - const struct snd_soc_component_driver *driver, - struct device *dev) + const struct snd_soc_component_driver *driver) { + struct device *dev = component->dev; + component->dapm = snd_soc_dapm_alloc(dev); if (!component->dapm) return -ENOMEM; @@ -2730,7 +2731,6 @@ static int soc_component_initialize(struct snd_soc_component *component, } } - component->dev = dev; component->driver = driver; return 0; @@ -2785,7 +2785,7 @@ int snd_soc_register_component_c(struct snd_soc_component *component, { int ret; - ret = soc_component_initialize(component, component_driver, component->dev); + ret = soc_component_initialize(component, component_driver); if (ret < 0) return ret;