aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-dapm.c
diff options
context:
space:
mode:
authorRyo Tsutsui <Ryo.Tsutsui@wolfsonmicro.com>2013-04-01 07:50:01 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-04-01 17:10:20 -0400
commit1059ecfa0f1eb38eba592b2f939499504013b6d5 (patch)
tree652d70f9557c6d60aecccaedc132d2c7b318f166 /sound/soc/soc-dapm.c
parent0e669246dcd11ad3ecb33a6170a963c4badaa10b (diff)
ASoC: dapm: Only clear paths we've walked
When clearing the walked flags there is no need to clear all paths, we only need to clear the paths we actually walked. This means we can split dapm_clear_walk() into input and output versions and rather than going through all DAPM paths we can recurse down the path until we encounter paths we have not yet walked. This reduces the number of operations we need to perform and improves cache locality. [Pulled out of the vendor tree that the patch was originally generated for by me, any bugs were introduced in that process -- broonie] Signed-off-by: Ryo Tsutsui <Ryo.Tsutsui@wolfsonmicro.com> Acked-by: Liam Girdwood <liam.r.girdwood@linux.intel.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r--sound/soc/soc-dapm.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 7a61b5cc2d4f..68acec667242 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -707,14 +707,33 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w)
707} 707}
708 708
709/* reset 'walked' bit for each dapm path */ 709/* reset 'walked' bit for each dapm path */
710static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm) 710static void dapm_clear_walk_output(struct snd_soc_dapm_context *dapm,
711 struct list_head *sink)
711{ 712{
712 struct snd_soc_dapm_path *p; 713 struct snd_soc_dapm_path *p;
713 714
714 list_for_each_entry(p, &dapm->card->paths, list) 715 list_for_each_entry(p, sink, list_source) {
715 p->walked = 0; 716 if (p->walked) {
717 p->walked = 0;
718 dapm_clear_walk_output(dapm, &p->sink->sinks);
719 }
720 }
721}
722
723static void dapm_clear_walk_input(struct snd_soc_dapm_context *dapm,
724 struct list_head *source)
725{
726 struct snd_soc_dapm_path *p;
727
728 list_for_each_entry(p, source, list_sink) {
729 if (p->walked) {
730 p->walked = 0;
731 dapm_clear_walk_input(dapm, &p->source->sources);
732 }
733 }
716} 734}
717 735
736
718/* We implement power down on suspend by checking the power state of 737/* We implement power down on suspend by checking the power state of
719 * the ALSA card - when we are suspending the ALSA state for the card 738 * the ALSA card - when we are suspending the ALSA state for the card
720 * is set to D3. 739 * is set to D3.
@@ -983,13 +1002,17 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
983 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 1002 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
984 dapm_reset(card); 1003 dapm_reset(card);
985 1004
986 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1005 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
987 paths = is_connected_output_ep(dai->playback_widget, list); 1006 paths = is_connected_output_ep(dai->playback_widget, list);
988 else 1007 dapm_clear_walk_output(&card->dapm,
1008 &dai->playback_widget->sinks);
1009 } else {
989 paths = is_connected_input_ep(dai->capture_widget, list); 1010 paths = is_connected_input_ep(dai->capture_widget, list);
1011 dapm_clear_walk_input(&card->dapm,
1012 &dai->capture_widget->sources);
1013 }
990 1014
991 trace_snd_soc_dapm_connected(paths, stream); 1015 trace_snd_soc_dapm_connected(paths, stream);
992 dapm_clear_walk(&card->dapm);
993 mutex_unlock(&card->dapm_mutex); 1016 mutex_unlock(&card->dapm_mutex);
994 1017
995 return paths; 1018 return paths;
@@ -1092,9 +1115,9 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
1092 DAPM_UPDATE_STAT(w, power_checks); 1115 DAPM_UPDATE_STAT(w, power_checks);
1093 1116
1094 in = is_connected_input_ep(w, NULL); 1117 in = is_connected_input_ep(w, NULL);
1095 dapm_clear_walk(w->dapm); 1118 dapm_clear_walk_input(w->dapm, &w->sources);
1096 out = is_connected_output_ep(w, NULL); 1119 out = is_connected_output_ep(w, NULL);
1097 dapm_clear_walk(w->dapm); 1120 dapm_clear_walk_output(w->dapm, &w->sinks);
1098 return out != 0 && in != 0; 1121 return out != 0 && in != 0;
1099} 1122}
1100 1123
@@ -1117,7 +1140,7 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
1117 1140
1118 if (w->active) { 1141 if (w->active) {
1119 in = is_connected_input_ep(w, NULL); 1142 in = is_connected_input_ep(w, NULL);
1120 dapm_clear_walk(w->dapm); 1143 dapm_clear_walk_input(w->dapm, &w->sources);
1121 return in != 0; 1144 return in != 0;
1122 } else { 1145 } else {
1123 return dapm_generic_check_power(w); 1146 return dapm_generic_check_power(w);
@@ -1133,7 +1156,7 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
1133 1156
1134 if (w->active) { 1157 if (w->active) {
1135 out = is_connected_output_ep(w, NULL); 1158 out = is_connected_output_ep(w, NULL);
1136 dapm_clear_walk(w->dapm); 1159 dapm_clear_walk_output(w->dapm, &w->sinks);
1137 return out != 0; 1160 return out != 0;
1138 } else { 1161 } else {
1139 return dapm_generic_check_power(w); 1162 return dapm_generic_check_power(w);
@@ -1745,9 +1768,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1745 return -ENOMEM; 1768 return -ENOMEM;
1746 1769
1747 in = is_connected_input_ep(w, NULL); 1770 in = is_connected_input_ep(w, NULL);
1748 dapm_clear_walk(w->dapm); 1771 dapm_clear_walk_input(w->dapm, &w->sources);
1749 out = is_connected_output_ep(w, NULL); 1772 out = is_connected_output_ep(w, NULL);
1750 dapm_clear_walk(w->dapm); 1773 dapm_clear_walk_output(w->dapm, &w->sinks);
1751 1774
1752 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d", 1775 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d",
1753 w->name, w->power ? "On" : "Off", 1776 w->name, w->power ? "On" : "Off",