ASoC: add and use new snd_soc_register_component()

Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> says:

Current component has component->name. But snd_soc_register_component()
user can't setup it, because component itself is alloced in that function.

So, to setup it, user need to use snd_soc_component_initialize() /
snd_soc_add_component() directly instead of using
snd_soc_register_component().

In the same time, Component will be capsuled soon.

Let's tidyup around here.
All strange code can be gone if we have both below style.

Normal case
	snd_soc_register_component(dev, ...);

Want to setup case
	component = snd_soc_component_alloc(...);

	snd_soc_component_set_xxx(component, ...);
	snd_soc_component_set_xxx(component, ...);

(A)	snd_soc_register_component(component, ...);

This patch-set adds new snd_soc_register_component() which allows to use
component (A).

Link: https://lore.kernel.org/r/87fr29esth.wl-kuninori.morimoto.gx@renesas.com
Link: https://lore.kernel.org/r/87v7ayxk3s.wl-kuninori.morimoto.gx@renesas.com
Link: https://lore.kernel.org/r/87zf04c1w5.wl-kuninori.morimoto.gx@renesas.com
Link: https://lore.kernel.org/r/87qzkxjg53.wl-kuninori.morimoto.gx@renesas.com
Link: https://patch.msgid.link/87y0f2rz8l.wl-kuninori.morimoto.gx@renesas.com
This commit is contained in:
Mark Brown 2026-08-05 00:39:37 +01:00
commit be80e848c1
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
23 changed files with 326 additions and 159 deletions

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)\
@ -283,6 +286,14 @@ 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_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);

View File

@ -447,15 +447,16 @@ 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(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);

View File

@ -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 = {

View File

@ -1077,7 +1077,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;
}
@ -1086,7 +1086,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);

View File

@ -2065,7 +2065,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;
}
@ -2076,7 +2076,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;
}
@ -2089,7 +2089,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;
}
@ -2102,7 +2102,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;

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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[] = {

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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];

View File

@ -29,17 +29,42 @@ 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)
struct snd_soc_component *snd_soc_component_alloc(struct device *dev)
{
if (!mask) {
dev_err(component->dev, "ASoC: error field mask is zero for %s\n",
component->name);
return 0;
}
struct snd_soc_component *component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL);
return (ffs(mask) - 1);
if (!component)
return NULL;
component->dev = dev;
return component;
}
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);
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.
@ -820,6 +845,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

View File

@ -2707,10 +2707,11 @@ 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->dev;
component->dapm = snd_soc_dapm_alloc(dev);
if (!component->dapm)
return -ENOMEM;
@ -2730,16 +2731,14 @@ int snd_soc_component_initialize(struct snd_soc_component *component,
}
}
component->dev = dev;
component->driver = driver;
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,27 +2777,36 @@ int snd_soc_add_component(struct snd_soc_component *component,
return ret;
}
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 = soc_component_initialize(component, component_driver);
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);
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

View File

@ -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);

View File

@ -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++) {

View File

@ -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)

View File

@ -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;

View File

@ -3461,6 +3461,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;
}
@ -3469,6 +3478,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)
@ -3477,6 +3489,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;
}

View File

@ -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;
}