aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-dapm.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-09-20 16:43:24 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-09-21 09:53:44 -0400
commitde02d0786d4075091f5b1860474cd21d85ff5862 (patch)
tree5767c43edb3ee26429b7ce1dd2e42a9f96a28965 /sound/soc/soc-dapm.c
parent6d4baf084f4d8dc43cf5d5a3c182018604afa80c (diff)
ASoC: Trace and collect statistics for DAPM graph walking
One of the longest standing areas for improvement in ASoC has been the DAPM algorithm - it repeats the same checks many times whenever it is run and makes no effort to limit the areas of the graph it checks meaning we do an awful lot of walks over the full graph. This has never mattered too much as the size of the graph has generally been small in relation to the size of the devices supported and the speed of CPUs but it is annoying. In preparation for work on improving this insert a trace point after the graph walk has been done. This gives us specific timing information for the walk, and in order to give quantifiable (non-benchmark) numbers also count every time we check a link or check the power for a widget and report those numbers. Substantial changes in the algorithm may require tweaks to the stats but they should be useful for simpler things. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r--sound/soc/soc-dapm.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 4a440b52dd7a..6a1e13ea996d 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -48,6 +48,8 @@
48 48
49#include <trace/events/asoc.h> 49#include <trace/events/asoc.h>
50 50
51#define DAPM_UPDATE_STAT(widget, val) widget->dapm->card->dapm_stats.val++;
52
51/* dapm power sequences - make this per codec in the future */ 53/* dapm power sequences - make this per codec in the future */
52static int dapm_up_seq[] = { 54static int dapm_up_seq[] = {
53 [snd_soc_dapm_pre] = 0, 55 [snd_soc_dapm_pre] = 0,
@@ -649,6 +651,8 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
649 struct snd_soc_dapm_path *path; 651 struct snd_soc_dapm_path *path;
650 int con = 0; 652 int con = 0;
651 653
654 DAPM_UPDATE_STAT(widget, path_checks);
655
652 if (widget->id == snd_soc_dapm_supply) 656 if (widget->id == snd_soc_dapm_supply)
653 return 0; 657 return 0;
654 658
@@ -697,6 +701,8 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
697 struct snd_soc_dapm_path *path; 701 struct snd_soc_dapm_path *path;
698 int con = 0; 702 int con = 0;
699 703
704 DAPM_UPDATE_STAT(widget, path_checks);
705
700 if (widget->id == snd_soc_dapm_supply) 706 if (widget->id == snd_soc_dapm_supply)
701 return 0; 707 return 0;
702 708
@@ -767,6 +773,8 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
767{ 773{
768 int in, out; 774 int in, out;
769 775
776 DAPM_UPDATE_STAT(w, power_checks);
777
770 in = is_connected_input_ep(w); 778 in = is_connected_input_ep(w);
771 dapm_clear_walk(w->dapm); 779 dapm_clear_walk(w->dapm);
772 out = is_connected_output_ep(w); 780 out = is_connected_output_ep(w);
@@ -779,6 +787,8 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
779{ 787{
780 int in; 788 int in;
781 789
790 DAPM_UPDATE_STAT(w, power_checks);
791
782 if (w->active) { 792 if (w->active) {
783 in = is_connected_input_ep(w); 793 in = is_connected_input_ep(w);
784 dapm_clear_walk(w->dapm); 794 dapm_clear_walk(w->dapm);
@@ -793,6 +803,8 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
793{ 803{
794 int out; 804 int out;
795 805
806 DAPM_UPDATE_STAT(w, power_checks);
807
796 if (w->active) { 808 if (w->active) {
797 out = is_connected_output_ep(w); 809 out = is_connected_output_ep(w);
798 dapm_clear_walk(w->dapm); 810 dapm_clear_walk(w->dapm);
@@ -808,6 +820,8 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
808 struct snd_soc_dapm_path *path; 820 struct snd_soc_dapm_path *path;
809 int power = 0; 821 int power = 0;
810 822
823 DAPM_UPDATE_STAT(w, power_checks);
824
811 /* Check if one of our outputs is connected */ 825 /* Check if one of our outputs is connected */
812 list_for_each_entry(path, &w->sinks, list_source) { 826 list_for_each_entry(path, &w->sinks, list_source) {
813 if (path->weak) 827 if (path->weak)
@@ -1208,6 +1222,8 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1208 } 1222 }
1209 } 1223 }
1210 1224
1225 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));
1226
1211 /* Check which widgets we need to power and store them in 1227 /* Check which widgets we need to power and store them in
1212 * lists indicating if they should be powered up or down. 1228 * lists indicating if they should be powered up or down.
1213 */ 1229 */
@@ -1299,6 +1315,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1299 list_for_each_entry(d, &card->dapm_list, list) 1315 list_for_each_entry(d, &card->dapm_list, list)
1300 d->target_bias_level = bias; 1316 d->target_bias_level = bias;
1301 1317
1318 trace_snd_soc_dapm_walk_done(card);
1302 1319
1303 /* Run all the bias changes in parallel */ 1320 /* Run all the bias changes in parallel */
1304 list_for_each_entry(d, &dapm->card->dapm_list, list) 1321 list_for_each_entry(d, &dapm->card->dapm_list, list)