]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ASoC: core: Move all users to deferrable card binding
authorCezary Rojewski <cezary.rojewski@intel.com>
Thu, 30 Apr 2026 14:07:52 +0000 (16:07 +0200)
committerMark Brown <broonie@kernel.org>
Mon, 11 May 2026 01:06:10 +0000 (10:06 +0900)
Commit a3375522bb5e2 ("ASoC: core: Complete support for card rebinding")
completed the feature and at the same time divided ASoC users into two
groups:

1) cards that fail to enumerate the moment one of the components is
   not available
2) cards that succeed to enumerate even if some of their components
   become available late

Given the component-based nature of ASoC, approach 2) is preferred and
can be used by all ASoC users.  By dropping 1) the card binding code can
also be simplified.

Flatten code that is currently conditional based on ->devres_dev and
convert snd_soc_rebind_card() to call_soc_bind_card().  The latter is a
selector between managed and unmanaged card-binding behaviour to keep
non-devm users happy.

With rebinding being the default, devm_snd_soc_register_card() takes
form of its deferrable friend - all the devm job is already done by
devm_snd_soc_bind_card().

Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://patch.msgid.link/20260430140752.766130-1-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
include/sound/soc.h
sound/soc/soc-core.c
sound/soc/soc-devres.c

index 5e3eb617d8323ac64a4d7567059363bf12606ade..50d1fd110a4ab1ceffde99cb2dae66fb25f94732 100644 (file)
@@ -431,7 +431,7 @@ struct snd_soc_jack_pin;
 int snd_soc_register_card(struct snd_soc_card *card);
 void snd_soc_unregister_card(struct snd_soc_card *card);
 int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card);
-int devm_snd_soc_register_deferrable_card(struct device *dev, struct snd_soc_card *card);
+#define devm_snd_soc_register_deferrable_card(d, c) devm_snd_soc_register_card(d, c)
 #ifdef CONFIG_PM_SLEEP
 int snd_soc_suspend(struct device *dev);
 int snd_soc_resume(struct device *dev);
index 3fecf9fc903c004c7c39f7ebca7f8291656c4257..1d9099595a88ef27311e64c89d7e2e6977da5d39 100644 (file)
@@ -2168,6 +2168,7 @@ static int snd_soc_bind_card(struct snd_soc_card *card)
        snd_soc_fill_dummy_dai(card);
 
        snd_soc_dapm_init(dapm, card, NULL);
+       list_del_init(&card->list);
 
        /* check whether any platform is ignore machine FE and using topology */
        soc_check_tplg_fes(card);
@@ -2311,6 +2312,10 @@ static int snd_soc_bind_card(struct snd_soc_card *card)
 probe_end:
        if (ret < 0)
                soc_cleanup_card_resources(card);
+       if (ret == -EPROBE_DEFER) {
+               list_add(&card->list, &unbind_card_list);
+               ret = 0;
+       }
        snd_soc_card_mutex_unlock(card);
 
        return ret;
@@ -2326,12 +2331,15 @@ static int devm_snd_soc_bind_card(struct device *dev, struct snd_soc_card *card)
        struct snd_soc_card **ptr;
        int ret;
 
+       /* The procedure may be called many times during the lifetime of the card. */
+       devres_destroy(dev, devm_card_bind_release, NULL, NULL);
+
        ptr = devres_alloc(devm_card_bind_release, sizeof(*ptr), GFP_KERNEL);
        if (!ptr)
                return -ENOMEM;
 
        ret = snd_soc_bind_card(card);
-       if (ret == 0 || ret == -EPROBE_DEFER) {
+       if (ret == 0) {
                *ptr = card;
                devres_add(dev, ptr);
        } else {
@@ -2341,21 +2349,11 @@ static int devm_snd_soc_bind_card(struct device *dev, struct snd_soc_card *card)
        return ret;
 }
 
-static int snd_soc_rebind_card(struct snd_soc_card *card)
+static int call_soc_bind_card(struct snd_soc_card *card)
 {
-       int ret;
-
-       if (card->devres_dev) {
-               devres_destroy(card->devres_dev, devm_card_bind_release, NULL, NULL);
-               ret = devm_snd_soc_bind_card(card->devres_dev, card);
-       } else {
-               ret = snd_soc_bind_card(card);
-       }
-
-       if (ret != -EPROBE_DEFER)
-               list_del_init(&card->list);
-
-       return ret;
+       if (card->devres_dev)
+               return devm_snd_soc_bind_card(card->devres_dev, card);
+       return snd_soc_bind_card(card);
 }
 
 /* probes a new socdev */
@@ -2553,8 +2551,6 @@ EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls);
  */
 int snd_soc_register_card(struct snd_soc_card *card)
 {
-       int ret;
-
        if (!card->name || !card->dev)
                return -EINVAL;
 
@@ -2580,17 +2576,7 @@ int snd_soc_register_card(struct snd_soc_card *card)
 
        guard(mutex)(&client_mutex);
 
-       if (card->devres_dev) {
-               ret = devm_snd_soc_bind_card(card->devres_dev, card);
-               if (ret == -EPROBE_DEFER) {
-                       list_add(&card->list, &unbind_card_list);
-                       ret = 0;
-               }
-       } else {
-               ret = snd_soc_bind_card(card);
-       }
-
-       return ret;
+       return call_soc_bind_card(card);
 }
 EXPORT_SYMBOL_GPL(snd_soc_register_card);
 
@@ -2910,7 +2896,7 @@ int snd_soc_add_component(struct snd_soc_component *component,
        list_add(&component->list, &component_list);
 
        list_for_each_entry_safe(card, c, &unbind_card_list, list)
-               snd_soc_rebind_card(card);
+               call_soc_bind_card(card);
 
 err_cleanup:
        if (ret < 0)
index d33f83ec24f27545b403b07943323633ca0fb290..718165ba84ac87f00ff709f415f3b0a68f97ae88 100644 (file)
@@ -49,11 +49,6 @@ int devm_snd_soc_register_component(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_snd_soc_register_component);
 
-static void devm_card_release(struct device *dev, void *res)
-{
-       snd_soc_unregister_card(*(struct snd_soc_card **)res);
-}
-
 /**
  * devm_snd_soc_register_card - resource managed card registration
  * @dev: Device used to manage card
@@ -63,32 +58,11 @@ static void devm_card_release(struct device *dev, void *res)
  * unregistered.
  */
 int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card)
-{
-       struct snd_soc_card **ptr;
-       int ret;
-
-       ptr = devres_alloc(devm_card_release, sizeof(*ptr), GFP_KERNEL);
-       if (!ptr)
-               return -ENOMEM;
-
-       ret = snd_soc_register_card(card);
-       if (ret == 0) {
-               *ptr = card;
-               devres_add(dev, ptr);
-       } else {
-               devres_free(ptr);
-       }
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(devm_snd_soc_register_card);
-
-int devm_snd_soc_register_deferrable_card(struct device *dev, struct snd_soc_card *card)
 {
        card->devres_dev = dev;
        return snd_soc_register_card(card);
 }
-EXPORT_SYMBOL_GPL(devm_snd_soc_register_deferrable_card);
+EXPORT_SYMBOL_GPL(devm_snd_soc_register_card);
 
 #ifdef CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM