@@ -1083,6 +1083,7 @@ struct snd_soc_card {
struct list_head paths;
struct list_head dapm_list;
struct list_head dapm_dirty;
+ struct list_head unbinded_list;
/* Generic DAPM context for the card */
struct snd_soc_dapm_context dapm;
@@ -56,6 +56,7 @@ static DEFINE_MUTEX(client_mutex);
static LIST_HEAD(platform_list);
static LIST_HEAD(codec_list);
static LIST_HEAD(component_list);
+static LIST_HEAD(unbinded_card_list);
/*
* This is a timeout to do a DAPM powerdown after a stream is closed().
@@ -2397,6 +2398,10 @@ int snd_soc_unregister_card(struct snd_soc_card *card)
card->name);
}
+ mutex_lock(&client_mutex);
+ list_del(&card->unbinded_list);
+ mutex_unlock(&client_mutex);
+
return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_unregister_card);
@@ -2660,6 +2665,9 @@ EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap);
static void snd_soc_component_add_unlocked(struct snd_soc_component *component)
{
+ struct snd_soc_card *card, *_card;
+ int ret;
+
if (!component->write && !component->read) {
if (!component->regmap)
component->regmap = dev_get_regmap(component->dev, NULL);
@@ -2668,6 +2676,16 @@ static void snd_soc_component_add_unlocked(struct snd_soc_component *component)
}
list_add(&component->list, &component_list);
+
+ /* re-add temporarily removed card if exist */
+ list_for_each_entry_safe(card, _card, &unbinded_card_list,
+ unbinded_list) {
+ ret = snd_soc_instantiate_card(card);
+ if (ret < 0)
+ continue;
+
+ list_del(&card->unbinded_list);
+ }
}
static void snd_soc_component_add(struct snd_soc_component *component)
@@ -2685,7 +2703,15 @@ static void snd_soc_component_cleanup(struct snd_soc_component *component)
static void snd_soc_component_del_unlocked(struct snd_soc_component *component)
{
+ struct snd_soc_card *card = component->card;
+
list_del(&component->list);
+
+ /* card is removed temporarily */
+ if (card->instantiated) {
+ list_add(&card->unbinded_list, &unbinded_card_list);
+ snd_soc_remove_card(card);
+ }
}
static void snd_soc_component_del(struct snd_soc_component *component)