@@ -52,6 +52,7 @@ EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);
52
52
53
53
static DEFINE_MUTEX (client_mutex );
54
54
static LIST_HEAD (component_list );
55
+ static LIST_HEAD (unbind_card_list );
55
56
56
57
/*
57
58
* 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,
2679
2680
}
2680
2681
EXPORT_SYMBOL_GPL (snd_soc_dai_digital_mute );
2681
2682
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
+
2682
2710
/**
2683
2711
* snd_soc_register_card - Register a card with the ASoC core
2684
2712
*
@@ -2688,7 +2716,6 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
2688
2716
int snd_soc_register_card (struct snd_soc_card * card )
2689
2717
{
2690
2718
int i , ret ;
2691
- struct snd_soc_pcm_runtime * rtd ;
2692
2719
2693
2720
if (!card -> name || !card -> dev )
2694
2721
return - EINVAL ;
@@ -2719,28 +2746,23 @@ int snd_soc_register_card(struct snd_soc_card *card)
2719
2746
mutex_init (& card -> mutex );
2720
2747
mutex_init (& card -> dapm_mutex );
2721
2748
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 );
2736
2752
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 );
2739
2764
}
2740
-
2741
- return ret ;
2742
2765
}
2743
- EXPORT_SYMBOL_GPL (snd_soc_register_card );
2744
2766
2745
2767
/**
2746
2768
* snd_soc_unregister_card - Unregister a card with the ASoC core
@@ -2750,12 +2772,8 @@ EXPORT_SYMBOL_GPL(snd_soc_register_card);
2750
2772
*/
2751
2773
int snd_soc_unregister_card (struct snd_soc_card * card )
2752
2774
{
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 );
2759
2777
2760
2778
return 0 ;
2761
2779
}
@@ -3099,7 +3117,7 @@ static void snd_soc_component_del_unlocked(struct snd_soc_component *component)
3099
3117
struct snd_soc_card * card = component -> card ;
3100
3118
3101
3119
if (card )
3102
- snd_soc_unregister_card (card );
3120
+ snd_soc_unbind_card (card , false );
3103
3121
3104
3122
list_del (& component -> list );
3105
3123
}
@@ -3139,6 +3157,18 @@ static void convert_endianness_formats(struct snd_soc_pcm_stream *stream)
3139
3157
stream -> formats |= endianness_format_map [i ];
3140
3158
}
3141
3159
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
+
3142
3172
int snd_soc_add_component (struct device * dev ,
3143
3173
struct snd_soc_component * component ,
3144
3174
const struct snd_soc_component_driver * component_driver ,
@@ -3166,6 +3196,7 @@ int snd_soc_add_component(struct device *dev,
3166
3196
}
3167
3197
3168
3198
snd_soc_component_add (component );
3199
+ snd_soc_try_rebind_card ();
3169
3200
3170
3201
return 0 ;
3171
3202
0 commit comments