aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2014-10-25 11:42:00 -0400
committerMark Brown <broonie@kernel.org>2014-10-27 20:19:59 -0400
commitc1862c8bae520a8986dd7c47ce33f16eb7c791c2 (patch)
tree793452d0f3bfd45881c1dc057d015f521a35f952
parent6dd98b0a3e58b7b48a422802b5610b95ef5128eb (diff)
ASoC: dapm: Add a flag to mark paths connected to supply widgets
Supply widgets do not count towards the input and output widgets of their neighbors and for supply widgets themselves we do not care for the number of input or output paths. This means that a path that connects to a supply widget effectively behaves the same as a path that as the weak property set. This patch adds a new path flag that gets set to true when the path is connected to at least one supply widget. If a path with the flag set is encountered in is_connected_{input,output}_ep() is is skipped in the same way that weak paths are skipped. This slightly brings down the number of path checks. Since both the weak and the supply flag are implemented as bitfields which are stored in the same word there is no runtime overhead due to checking both rather than just one and also the size of the path struct is not increased by this patch. Another advantage is that we do not have to handle supply widgets in is_connected_{input,output}_ep() anymore since it will never be called for supply widgets. The only exception is from dapm_widget_power_read_file() where a check is added to special case supply widgets. Testing with the ADAU1761, which has a handful of supply widgets, shows the following changes in the DAPM stats for a playback stream start. Power Path Neighbour Before: 34 78 117 After: 34 48 117 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.c23
2 files changed, 14 insertions, 10 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 8cf3aad30864..e7ebeb717482 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -510,6 +510,7 @@ struct snd_soc_dapm_path {
510 u32 connect:1; /* source and sink widgets are connected */ 510 u32 connect:1; /* source and sink widgets are connected */
511 u32 walking:1; /* path is in the process of being walked */ 511 u32 walking:1; /* path is in the process of being walked */
512 u32 weak:1; /* path ignored for power management */ 512 u32 weak:1; /* path ignored for power management */
513 u32 is_supply:1; /* At least one of the connected widgets is a supply */
513 514
514 int (*connected)(struct snd_soc_dapm_widget *source, 515 int (*connected)(struct snd_soc_dapm_widget *source,
515 struct snd_soc_dapm_widget *sink); 516 struct snd_soc_dapm_widget *sink);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 2cad5f77ec60..d89be153a9e0 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -821,9 +821,6 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
821 821
822 DAPM_UPDATE_STAT(widget, path_checks); 822 DAPM_UPDATE_STAT(widget, path_checks);
823 823
824 if (widget->is_supply)
825 return 0;
826
827 if (widget->is_sink && widget->connected) { 824 if (widget->is_sink && widget->connected) {
828 widget->outputs = snd_soc_dapm_suspend_check(widget); 825 widget->outputs = snd_soc_dapm_suspend_check(widget);
829 return widget->outputs; 826 return widget->outputs;
@@ -832,7 +829,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
832 list_for_each_entry(path, &widget->sinks, list_source) { 829 list_for_each_entry(path, &widget->sinks, list_source) {
833 DAPM_UPDATE_STAT(widget, neighbour_checks); 830 DAPM_UPDATE_STAT(widget, neighbour_checks);
834 831
835 if (path->weak) 832 if (path->weak || path->is_supply)
836 continue; 833 continue;
837 834
838 if (path->walking) 835 if (path->walking)
@@ -882,9 +879,6 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
882 879
883 DAPM_UPDATE_STAT(widget, path_checks); 880 DAPM_UPDATE_STAT(widget, path_checks);
884 881
885 if (widget->is_supply)
886 return 0;
887
888 if (widget->is_source && widget->connected) { 882 if (widget->is_source && widget->connected) {
889 widget->inputs = snd_soc_dapm_suspend_check(widget); 883 widget->inputs = snd_soc_dapm_suspend_check(widget);
890 return widget->inputs; 884 return widget->inputs;
@@ -893,7 +887,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
893 list_for_each_entry(path, &widget->sources, list_sink) { 887 list_for_each_entry(path, &widget->sources, list_sink) {
894 DAPM_UPDATE_STAT(widget, neighbour_checks); 888 DAPM_UPDATE_STAT(widget, neighbour_checks);
895 889
896 if (path->weak) 890 if (path->weak || path->is_supply)
897 continue; 891 continue;
898 892
899 if (path->walking) 893 if (path->walking)
@@ -1691,8 +1685,14 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1691 if (!buf) 1685 if (!buf)
1692 return -ENOMEM; 1686 return -ENOMEM;
1693 1687
1694 in = is_connected_input_ep(w, NULL); 1688 /* Supply widgets are not handled by is_connected_{input,output}_ep() */
1695 out = is_connected_output_ep(w, NULL); 1689 if (w->is_supply) {
1690 in = 0;
1691 out = 0;
1692 } else {
1693 in = is_connected_input_ep(w, NULL);
1694 out = is_connected_output_ep(w, NULL);
1695 }
1696 1696
1697 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d", 1697 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d",
1698 w->name, w->power ? "On" : "Off", 1698 w->name, w->power ? "On" : "Off",
@@ -2213,6 +2213,9 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm,
2213 INIT_LIST_HEAD(&path->list_source); 2213 INIT_LIST_HEAD(&path->list_source);
2214 INIT_LIST_HEAD(&path->list_sink); 2214 INIT_LIST_HEAD(&path->list_sink);
2215 2215
2216 if (wsource->is_supply || wsink->is_supply)
2217 path->is_supply = 1;
2218
2216 /* connect static paths */ 2219 /* connect static paths */
2217 if (control == NULL) { 2220 if (control == NULL) {
2218 path->connect = 1; 2221 path->connect = 1;