From 0f2bec6921f0971c2fc2f8bb5a93229b6546dded Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 7 Oct 2026 15:33:47 +0200 Subject: [PATCH] ASoC: core: Add component constructor There is a gap between snd_soc_component_alloc() and snd_soc_register_component(). A driver that obtains a component object through snd_soc_component_alloc() receives an object in uninitialized state. soc_component_initialize() is the function responsible for bringing it into a sane one but it is not accessible by the framework users. The framework shall prevent manipulation of uninitialized components. Introduce snd_soc_component_new() which acts as a constructor: allocates and initializes the component object before returning it to the caller. Cc: Kuninori Morimoto Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20261007133353.455185-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- include/sound/soc-component.h | 2 ++ sound/soc/soc-core.c | 44 +++++++++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h index 6c1acc984ecb..d51f71e2f334 100644 --- a/include/sound/soc-component.h +++ b/include/sound/soc-component.h @@ -292,6 +292,8 @@ static inline int snd_soc_component_cache_sync( return regcache_sync(component->regmap); } +struct snd_soc_component *snd_soc_component_new(struct device *dev, const char *name, + const struct snd_soc_component_driver *driver); 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); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 06167a198591..c4de336ab408 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2589,6 +2589,42 @@ static int soc_component_initialize(struct snd_soc_component *component, return 0; } +struct snd_soc_component *snd_soc_component_new(struct device *dev, const char *name, + const struct snd_soc_component_driver *driver) +{ + struct snd_soc_component *component; + + component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL); + if (!component) + return ERR_PTR(-ENOMEM); + + component->dapm = snd_soc_dapm_alloc(dev); + if (!component->dapm) + return ERR_PTR(-ENOMEM); + + if (!name) { + name = snd_soc_fmt_single_name(dev, NULL); + if (!name) { + dev_err(dev, "ASoC: Failed to allocate name\n"); + return ERR_PTR(-ENOMEM); + } + } + + component->dev = dev; + component->name = name; + component->driver = driver; + + INIT_LIST_HEAD(&component->dai_list); + INIT_LIST_HEAD(&component->dobj_list); + INIT_LIST_HEAD(&component->card_list); + INIT_LIST_HEAD(&component->list); + INIT_LIST_HEAD(&component->card_aux_list); + mutex_init(&component->io_mutex); + + return component; +} +EXPORT_SYMBOL_GPL(snd_soc_component_new); + static int soc_component_add(struct snd_soc_component *component, struct snd_soc_dai_driver *dai_drv, int num_dai) @@ -2653,11 +2689,11 @@ int snd_soc_register_component_d(struct device *dev, { struct snd_soc_component *component; - component = snd_soc_component_alloc(dev); - if (!component) - return -ENOMEM; + component = snd_soc_component_new(dev, NULL, component_driver); + if (IS_ERR(component)) + return PTR_ERR(component); - return snd_soc_register_component_c(component, component_driver, dai_drv, num_dai); + return soc_component_add(component, dai_drv, num_dai); } EXPORT_SYMBOL_GPL(snd_soc_register_component_d);