Skip to content

Commit e894efe

Browse files
Srinivas-Kandagatlabroonie
authored andcommitted
ASoC: core: add support to card rebind
Current behaviour of ASoC core w.r.t to component removal is that it unregisters dependent sound card totally. There is no support to rebind the card if the component comes back. Typical use case is DSP restart or kernel modules itself. With this patch, core now maintains list of cards that are unbind due to any of its depended components are removed and card not unregistered yet. This list is cleared when the card is rebind successfully or when the card is unregistered from machine driver. This list of unbind cards are tried to bind once again after every new component is successfully added, giving a fair chance for card bind to be successful. Signed-off-by: Srinivas Kandagatla <[email protected]> Signed-off-by: Mark Brown <[email protected]>
1 parent e1e38ea commit e894efe

File tree

2 files changed

+60
-27
lines changed

2 files changed

+60
-27
lines changed

include/sound/soc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,7 @@ struct snd_soc_card {
10971097

10981098
/* lists of probed devices belonging to this card */
10991099
struct list_head component_dev_list;
1100+
struct list_head list;
11001101

11011102
struct list_head widgets;
11021103
struct list_head paths;
@@ -1373,6 +1374,7 @@ static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
13731374
INIT_LIST_HEAD(&card->dapm_list);
13741375
INIT_LIST_HEAD(&card->aux_comp_list);
13751376
INIT_LIST_HEAD(&card->component_dev_list);
1377+
INIT_LIST_HEAD(&card->list);
13761378
}
13771379

13781380
static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc)

sound/soc/soc-core.c

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);
5252

5353
static DEFINE_MUTEX(client_mutex);
5454
static LIST_HEAD(component_list);
55+
static LIST_HEAD(unbind_card_list);
5556

5657
/*
5758
* This is a timeout to do a DAPM powerdown after a stream is closed().
@@ -2679,6 +2680,33 @@ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
26792680
}
26802681
EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
26812682

2683+
static int snd_soc_bind_card(struct snd_soc_card *card)
2684+
{
2685+
struct snd_soc_pcm_runtime *rtd;
2686+
int ret;
2687+
2688+
ret = snd_soc_instantiate_card(card);
2689+
if (ret != 0)
2690+
return ret;
2691+
2692+
/* deactivate pins to sleep state */
2693+
list_for_each_entry(rtd, &card->rtd_list, list) {
2694+
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
2695+
struct snd_soc_dai *codec_dai;
2696+
int j;
2697+
2698+
for_each_rtd_codec_dai(rtd, j, codec_dai) {
2699+
if (!codec_dai->active)
2700+
pinctrl_pm_select_sleep_state(codec_dai->dev);
2701+
}
2702+
2703+
if (!cpu_dai->active)
2704+
pinctrl_pm_select_sleep_state(cpu_dai->dev);
2705+
}
2706+
2707+
return ret;
2708+
}
2709+
26822710
/**
26832711
* snd_soc_register_card - Register a card with the ASoC core
26842712
*
@@ -2688,7 +2716,6 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
26882716
int snd_soc_register_card(struct snd_soc_card *card)
26892717
{
26902718
int i, ret;
2691-
struct snd_soc_pcm_runtime *rtd;
26922719

26932720
if (!card->name || !card->dev)
26942721
return -EINVAL;
@@ -2719,28 +2746,23 @@ int snd_soc_register_card(struct snd_soc_card *card)
27192746
mutex_init(&card->mutex);
27202747
mutex_init(&card->dapm_mutex);
27212748

2722-
ret = snd_soc_instantiate_card(card);
2723-
if (ret != 0)
2724-
return ret;
2725-
2726-
/* deactivate pins to sleep state */
2727-
list_for_each_entry(rtd, &card->rtd_list, list) {
2728-
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
2729-
struct snd_soc_dai *codec_dai;
2730-
int j;
2731-
2732-
for_each_rtd_codec_dai(rtd, j, codec_dai) {
2733-
if (!codec_dai->active)
2734-
pinctrl_pm_select_sleep_state(codec_dai->dev);
2735-
}
2749+
return snd_soc_bind_card(card);
2750+
}
2751+
EXPORT_SYMBOL_GPL(snd_soc_register_card);
27362752

2737-
if (!cpu_dai->active)
2738-
pinctrl_pm_select_sleep_state(cpu_dai->dev);
2753+
static void snd_soc_unbind_card(struct snd_soc_card *card, bool unregister)
2754+
{
2755+
if (card->instantiated) {
2756+
card->instantiated = false;
2757+
snd_soc_dapm_shutdown(card);
2758+
soc_cleanup_card_resources(card);
2759+
if (!unregister)
2760+
list_add(&card->list, &unbind_card_list);
2761+
} else {
2762+
if (unregister)
2763+
list_del(&card->list);
27392764
}
2740-
2741-
return ret;
27422765
}
2743-
EXPORT_SYMBOL_GPL(snd_soc_register_card);
27442766

27452767
/**
27462768
* snd_soc_unregister_card - Unregister a card with the ASoC core
@@ -2750,12 +2772,8 @@ EXPORT_SYMBOL_GPL(snd_soc_register_card);
27502772
*/
27512773
int snd_soc_unregister_card(struct snd_soc_card *card)
27522774
{
2753-
if (card->instantiated) {
2754-
card->instantiated = false;
2755-
snd_soc_dapm_shutdown(card);
2756-
soc_cleanup_card_resources(card);
2757-
dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name);
2758-
}
2775+
snd_soc_unbind_card(card, true);
2776+
dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name);
27592777

27602778
return 0;
27612779
}
@@ -3099,7 +3117,7 @@ static void snd_soc_component_del_unlocked(struct snd_soc_component *component)
30993117
struct snd_soc_card *card = component->card;
31003118

31013119
if (card)
3102-
snd_soc_unregister_card(card);
3120+
snd_soc_unbind_card(card, false);
31033121

31043122
list_del(&component->list);
31053123
}
@@ -3139,6 +3157,18 @@ static void convert_endianness_formats(struct snd_soc_pcm_stream *stream)
31393157
stream->formats |= endianness_format_map[i];
31403158
}
31413159

3160+
static void snd_soc_try_rebind_card(void)
3161+
{
3162+
struct snd_soc_card *card, *c;
3163+
3164+
if (!list_empty(&unbind_card_list)) {
3165+
list_for_each_entry_safe(card, c, &unbind_card_list, list) {
3166+
if (!snd_soc_bind_card(card))
3167+
list_del(&card->list);
3168+
}
3169+
}
3170+
}
3171+
31423172
int snd_soc_add_component(struct device *dev,
31433173
struct snd_soc_component *component,
31443174
const struct snd_soc_component_driver *component_driver,
@@ -3166,6 +3196,7 @@ int snd_soc_add_component(struct device *dev,
31663196
}
31673197

31683198
snd_soc_component_add(component);
3199+
snd_soc_try_rebind_card();
31693200

31703201
return 0;
31713202

0 commit comments

Comments
 (0)