ASoC: dapm: Reorder the bias update sequence
authorXiang Xiao <xiaoxiang@xiaomi.com>
Sat, 1 Mar 2014 16:04:03 +0000 (00:04 +0800)
committerMark Brown <broonie@linaro.org>
Mon, 3 Mar 2014 04:47:40 +0000 (12:47 +0800)
The new sequence ensure that dapm_pre_sequence_async work on
the card before all codecs and dapm_post_sequence_async work
on the card after all codecs.
So the machine driver could utilize the determinate sequence
to do the gloabl setup and teardown in the right place.

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
sound/soc/soc-dapm.c

index d856e7c4c631ab36e4e79c5fe0d52910a4563b28..77743e51420a8d8a3a7b3371f998b9e50176e6a5 100644 (file)
@@ -1898,10 +1898,14 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
 
        trace_snd_soc_dapm_walk_done(card);
 
-       /* Run all the bias changes in parallel */
-       list_for_each_entry(d, &card->dapm_list, list)
-               async_schedule_domain(dapm_pre_sequence_async, d,
-                                       &async_domain);
+       /* Run card bias changes at first */
+       dapm_pre_sequence_async(&card->dapm, 0);
+       /* Run other bias changes in parallel */
+       list_for_each_entry(d, &card->dapm_list, list) {
+               if (d != &card->dapm)
+                       async_schedule_domain(dapm_pre_sequence_async, d,
+                                               &async_domain);
+       }
        async_synchronize_full_domain(&async_domain);
 
        list_for_each_entry(w, &down_list, power_list) {
@@ -1921,10 +1925,14 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
        dapm_seq_run(card, &up_list, event, true);
 
        /* Run all the bias changes in parallel */
-       list_for_each_entry(d, &card->dapm_list, list)
-               async_schedule_domain(dapm_post_sequence_async, d,
-                                       &async_domain);
+       list_for_each_entry(d, &card->dapm_list, list) {
+               if (d != &card->dapm)
+                       async_schedule_domain(dapm_post_sequence_async, d,
+                                               &async_domain);
+       }
        async_synchronize_full_domain(&async_domain);
+       /* Run card bias changes at last */
+       dapm_post_sequence_async(&card->dapm, 0);
 
        /* do we need to notify any clients that DAPM event is complete */
        list_for_each_entry(d, &card->dapm_list, list) {
@@ -4159,11 +4167,18 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card)
        struct snd_soc_dapm_context *dapm;
 
        list_for_each_entry(dapm, &card->dapm_list, list) {
-               soc_dapm_shutdown_dapm(dapm);
-               if (dapm->bias_level == SND_SOC_BIAS_STANDBY)
-                       snd_soc_dapm_set_bias_level(dapm,
-                                                   SND_SOC_BIAS_OFF);
+               if (dapm != &card->dapm) {
+                       soc_dapm_shutdown_dapm(dapm);
+                       if (dapm->bias_level == SND_SOC_BIAS_STANDBY)
+                               snd_soc_dapm_set_bias_level(dapm,
+                                                           SND_SOC_BIAS_OFF);
+               }
        }
+
+       soc_dapm_shutdown_dapm(&card->dapm);
+       if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY)
+               snd_soc_dapm_set_bias_level(&card->dapm,
+                                           SND_SOC_BIAS_OFF);
 }
 
 /* Module information */