diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-10-09 06:52:05 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-10-09 07:07:48 -0400 |
commit | 024dc078558e64e4cebc62c096285430a61dd10e (patch) | |
tree | f1bc9f20c69d1245e1c7d70d384f3c17bcbdfa8c /sound/soc/soc-dapm.c | |
parent | 7ca3a18b055ac6667f4e7e34eae6637270002402 (diff) |
ASoC: Cache connected input and output recursions
The number of connected input and output endpoints for a given widgets
can't change during a DAPM run so there is no need to redo the recursion
through branches of the tree we've already visited. Doing this on one of
my test systems gives an improvement of:
Power Path Neighbour
Before: 63 607 731
After: 63 141 181
which scales up well as more widgets are involved in paths.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r-- | sound/soc/soc-dapm.c | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 22fb7355b134..258326b031cf 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -665,6 +665,9 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget) | |||
665 | struct snd_soc_dapm_path *path; | 665 | struct snd_soc_dapm_path *path; |
666 | int con = 0; | 666 | int con = 0; |
667 | 667 | ||
668 | if (widget->outputs >= 0) | ||
669 | return widget->outputs; | ||
670 | |||
668 | DAPM_UPDATE_STAT(widget, path_checks); | 671 | DAPM_UPDATE_STAT(widget, path_checks); |
669 | 672 | ||
670 | if (widget->id == snd_soc_dapm_supply) | 673 | if (widget->id == snd_soc_dapm_supply) |
@@ -673,21 +676,29 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget) | |||
673 | switch (widget->id) { | 676 | switch (widget->id) { |
674 | case snd_soc_dapm_adc: | 677 | case snd_soc_dapm_adc: |
675 | case snd_soc_dapm_aif_out: | 678 | case snd_soc_dapm_aif_out: |
676 | if (widget->active) | 679 | if (widget->active) { |
677 | return snd_soc_dapm_suspend_check(widget); | 680 | widget->outputs = snd_soc_dapm_suspend_check(widget); |
681 | return widget->outputs; | ||
682 | } | ||
678 | default: | 683 | default: |
679 | break; | 684 | break; |
680 | } | 685 | } |
681 | 686 | ||
682 | if (widget->connected) { | 687 | if (widget->connected) { |
683 | /* connected pin ? */ | 688 | /* connected pin ? */ |
684 | if (widget->id == snd_soc_dapm_output && !widget->ext) | 689 | if (widget->id == snd_soc_dapm_output && !widget->ext) { |
685 | return snd_soc_dapm_suspend_check(widget); | 690 | widget->outputs = snd_soc_dapm_suspend_check(widget); |
691 | return widget->outputs; | ||
692 | } | ||
686 | 693 | ||
687 | /* connected jack or spk ? */ | 694 | /* connected jack or spk ? */ |
688 | if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk || | 695 | if (widget->id == snd_soc_dapm_hp || |
689 | (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources))) | 696 | widget->id == snd_soc_dapm_spk || |
690 | return snd_soc_dapm_suspend_check(widget); | 697 | (widget->id == snd_soc_dapm_line && |
698 | !list_empty(&widget->sources))) { | ||
699 | widget->outputs = snd_soc_dapm_suspend_check(widget); | ||
700 | return widget->outputs; | ||
701 | } | ||
691 | } | 702 | } |
692 | 703 | ||
693 | list_for_each_entry(path, &widget->sinks, list_source) { | 704 | list_for_each_entry(path, &widget->sinks, list_source) { |
@@ -705,6 +716,8 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget) | |||
705 | } | 716 | } |
706 | } | 717 | } |
707 | 718 | ||
719 | widget->outputs = con; | ||
720 | |||
708 | return con; | 721 | return con; |
709 | } | 722 | } |
710 | 723 | ||
@@ -717,6 +730,9 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) | |||
717 | struct snd_soc_dapm_path *path; | 730 | struct snd_soc_dapm_path *path; |
718 | int con = 0; | 731 | int con = 0; |
719 | 732 | ||
733 | if (widget->inputs >= 0) | ||
734 | return widget->inputs; | ||
735 | |||
720 | DAPM_UPDATE_STAT(widget, path_checks); | 736 | DAPM_UPDATE_STAT(widget, path_checks); |
721 | 737 | ||
722 | if (widget->id == snd_soc_dapm_supply) | 738 | if (widget->id == snd_soc_dapm_supply) |
@@ -726,25 +742,35 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) | |||
726 | switch (widget->id) { | 742 | switch (widget->id) { |
727 | case snd_soc_dapm_dac: | 743 | case snd_soc_dapm_dac: |
728 | case snd_soc_dapm_aif_in: | 744 | case snd_soc_dapm_aif_in: |
729 | if (widget->active) | 745 | if (widget->active) { |
730 | return snd_soc_dapm_suspend_check(widget); | 746 | widget->inputs = snd_soc_dapm_suspend_check(widget); |
747 | return widget->inputs; | ||
748 | } | ||
731 | default: | 749 | default: |
732 | break; | 750 | break; |
733 | } | 751 | } |
734 | 752 | ||
735 | if (widget->connected) { | 753 | if (widget->connected) { |
736 | /* connected pin ? */ | 754 | /* connected pin ? */ |
737 | if (widget->id == snd_soc_dapm_input && !widget->ext) | 755 | if (widget->id == snd_soc_dapm_input && !widget->ext) { |
738 | return snd_soc_dapm_suspend_check(widget); | 756 | widget->inputs = snd_soc_dapm_suspend_check(widget); |
757 | return widget->inputs; | ||
758 | } | ||
739 | 759 | ||
740 | /* connected VMID/Bias for lower pops */ | 760 | /* connected VMID/Bias for lower pops */ |
741 | if (widget->id == snd_soc_dapm_vmid) | 761 | if (widget->id == snd_soc_dapm_vmid) { |
742 | return snd_soc_dapm_suspend_check(widget); | 762 | widget->inputs = snd_soc_dapm_suspend_check(widget); |
763 | return widget->inputs; | ||
764 | } | ||
743 | 765 | ||
744 | /* connected jack ? */ | 766 | /* connected jack ? */ |
745 | if (widget->id == snd_soc_dapm_mic || | 767 | if (widget->id == snd_soc_dapm_mic || |
746 | (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks))) | 768 | (widget->id == snd_soc_dapm_line && |
747 | return snd_soc_dapm_suspend_check(widget); | 769 | !list_empty(&widget->sinks))) { |
770 | widget->inputs = snd_soc_dapm_suspend_check(widget); | ||
771 | return widget->inputs; | ||
772 | } | ||
773 | |||
748 | } | 774 | } |
749 | 775 | ||
750 | list_for_each_entry(path, &widget->sources, list_sink) { | 776 | list_for_each_entry(path, &widget->sources, list_sink) { |
@@ -762,6 +788,8 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) | |||
762 | } | 788 | } |
763 | } | 789 | } |
764 | 790 | ||
791 | widget->inputs = con; | ||
792 | |||
765 | return con; | 793 | return con; |
766 | } | 794 | } |
767 | 795 | ||
@@ -1335,6 +1363,8 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) | |||
1335 | 1363 | ||
1336 | list_for_each_entry(w, &card->widgets, list) { | 1364 | list_for_each_entry(w, &card->widgets, list) { |
1337 | w->power_checked = false; | 1365 | w->power_checked = false; |
1366 | w->inputs = -1; | ||
1367 | w->outputs = -1; | ||
1338 | } | 1368 | } |
1339 | 1369 | ||
1340 | /* Check which widgets we need to power and store them in | 1370 | /* Check which widgets we need to power and store them in |