aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2014-10-20 13:36:39 -0400
committerMark Brown <broonie@kernel.org>2014-10-22 07:11:38 -0400
commit130897ac5ac03adb4604d27497c378c64c7b22dd (patch)
treea47a4365ff53420b96e1eb3ad28ca0c0757e0312
parentcdef2ad3ae64cc1ab2daeff26335e0dde988eed7 (diff)
ASoC: dapm: Remove path 'walked' flag
The 'walked' flag was used to avoid walking paths that have already been walked. But since we started caching the number of inputs and outputs of a path we never actually get into a situation where we try to walk a path that has the 'walked' flag set. There are two cases in which we can end up walking a path multiple times within a single run of is_connected_output_ep() or is_connected_input_ep(). 1) If a path splits up and rejoins later: .--> C ---v A -> B E --> F '--> D ---^ When walking from A to F we'll end up at E twice, once via C and once via D. But since we do a depth first search we'll fully discover the path and initialize the number of outputs/inputs of the widget the first time we get there. The second time we get there we'll use the cached value and not bother to check any of the paths again. So we'll never see a path where 'walked' is set in this case. 2) If there is a circle: A --> B <-- C <-.--> F '--> D ---' When walking from A to F we'll end up twice at B. But since there is a circle the 'walking' flag will still be set on B once we get there the second time. This means we won't look at any of it's outgoing paths. So in this case we won't ever see a path where 'walked' is set either. So it is safe to remove the flag. This on one hand means we remove some always true checks from one of the hottest paths of the DAPM algorithm and on the other hand means we do not have to do the tedious clearing of the flag after checking the number inputs or outputs of a widget. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--include/sound/soc-dapm.h1
-rw-r--r--sound/soc/soc-dapm.c49
2 files changed, 2 insertions, 48 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 3a4d7da67b8d..ebb93f29e4f3 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -508,7 +508,6 @@ struct snd_soc_dapm_path {
508 508
509 /* status */ 509 /* status */
510 u32 connect:1; /* source and sink widgets are connected */ 510 u32 connect:1; /* source and sink widgets are connected */
511 u32 walked:1; /* path has been walked */
512 u32 walking:1; /* path is in the process of being walked */ 511 u32 walking:1; /* path is in the process of being walked */
513 u32 weak:1; /* path ignored for power management */ 512 u32 weak:1; /* path ignored for power management */
514 513
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 219d73c27a8c..f03e0cfc65be 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -754,34 +754,6 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w)
754 return 0; 754 return 0;
755} 755}
756 756
757/* reset 'walked' bit for each dapm path */
758static void dapm_clear_walk_output(struct snd_soc_dapm_context *dapm,
759 struct list_head *sink)
760{
761 struct snd_soc_dapm_path *p;
762
763 list_for_each_entry(p, sink, list_source) {
764 if (p->walked) {
765 p->walked = 0;
766 dapm_clear_walk_output(dapm, &p->sink->sinks);
767 }
768 }
769}
770
771static void dapm_clear_walk_input(struct snd_soc_dapm_context *dapm,
772 struct list_head *source)
773{
774 struct snd_soc_dapm_path *p;
775
776 list_for_each_entry(p, source, list_sink) {
777 if (p->walked) {
778 p->walked = 0;
779 dapm_clear_walk_input(dapm, &p->source->sources);
780 }
781 }
782}
783
784
785/* We implement power down on suspend by checking the power state of 757/* We implement power down on suspend by checking the power state of
786 * the ALSA card - when we are suspending the ALSA state for the card 758 * the ALSA card - when we are suspending the ALSA state for the card
787 * is set to D3. 759 * is set to D3.
@@ -904,13 +876,9 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
904 if (path->walking) 876 if (path->walking)
905 return 1; 877 return 1;
906 878
907 if (path->walked)
908 continue;
909
910 trace_snd_soc_dapm_output_path(widget, path); 879 trace_snd_soc_dapm_output_path(widget, path);
911 880
912 if (path->connect) { 881 if (path->connect) {
913 path->walked = 1;
914 path->walking = 1; 882 path->walking = 1;
915 883
916 /* do we need to add this widget to the list ? */ 884 /* do we need to add this widget to the list ? */
@@ -1012,13 +980,9 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
1012 if (path->walking) 980 if (path->walking)
1013 return 1; 981 return 1;
1014 982
1015 if (path->walked)
1016 continue;
1017
1018 trace_snd_soc_dapm_input_path(widget, path); 983 trace_snd_soc_dapm_input_path(widget, path);
1019 984
1020 if (path->connect) { 985 if (path->connect) {
1021 path->walked = 1;
1022 path->walking = 1; 986 path->walking = 1;
1023 987
1024 /* do we need to add this widget to the list ? */ 988 /* do we need to add this widget to the list ? */
@@ -1066,15 +1030,10 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
1066 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 1030 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
1067 dapm_reset(card); 1031 dapm_reset(card);
1068 1032
1069 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 1033 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
1070 paths = is_connected_output_ep(dai->playback_widget, list); 1034 paths = is_connected_output_ep(dai->playback_widget, list);
1071 dapm_clear_walk_output(&card->dapm, 1035 else
1072 &dai->playback_widget->sinks);
1073 } else {
1074 paths = is_connected_input_ep(dai->capture_widget, list); 1036 paths = is_connected_input_ep(dai->capture_widget, list);
1075 dapm_clear_walk_input(&card->dapm,
1076 &dai->capture_widget->sources);
1077 }
1078 1037
1079 trace_snd_soc_dapm_connected(paths, stream); 1038 trace_snd_soc_dapm_connected(paths, stream);
1080 mutex_unlock(&card->dapm_mutex); 1039 mutex_unlock(&card->dapm_mutex);
@@ -1163,9 +1122,7 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
1163 DAPM_UPDATE_STAT(w, power_checks); 1122 DAPM_UPDATE_STAT(w, power_checks);
1164 1123
1165 in = is_connected_input_ep(w, NULL); 1124 in = is_connected_input_ep(w, NULL);
1166 dapm_clear_walk_input(w->dapm, &w->sources);
1167 out = is_connected_output_ep(w, NULL); 1125 out = is_connected_output_ep(w, NULL);
1168 dapm_clear_walk_output(w->dapm, &w->sinks);
1169 return out != 0 && in != 0; 1126 return out != 0 && in != 0;
1170} 1127}
1171 1128
@@ -1823,9 +1780,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1823 return -ENOMEM; 1780 return -ENOMEM;
1824 1781
1825 in = is_connected_input_ep(w, NULL); 1782 in = is_connected_input_ep(w, NULL);
1826 dapm_clear_walk_input(w->dapm, &w->sources);
1827 out = is_connected_output_ep(w, NULL); 1783 out = is_connected_output_ep(w, NULL);
1828 dapm_clear_walk_output(w->dapm, &w->sinks);
1829 1784
1830 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d", 1785 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d",
1831 w->name, w->power ? "On" : "Off", 1786 w->name, w->power ? "On" : "Off",