Commit 9b8a83b2 authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: Only run power_check() on a widget once per run



Some widgets will get power_check() run on them more than once during a
DAPM run, most commonly due to supply widgets checking to see if their
consumers are powered up. It's wasteful to do this so cache the result
of power_check() during a run. For one system I tested this on I got an
improvement of:

           Power    Path   Neighbour
Before:    106      970    1186
After:     69       727    905

from this.

Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 75c1f891
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -473,6 +473,8 @@ struct snd_soc_dapm_widget {
	unsigned char ext:1;			/* has external widgets */
	unsigned char force:1;			/* force state */
	unsigned char ignore_suspend:1;         /* kept enabled over suspend */
	unsigned char new_power:1;		/* power from this run */
	unsigned char power_checked:1;		/* power checked this run */
	int subseq;				/* sort within widget type */

	int (*power_check)(struct snd_soc_dapm_widget *w);
+13 −2
Original line number Diff line number Diff line
@@ -787,10 +787,17 @@ EXPORT_SYMBOL_GPL(dapm_reg_event);

static int dapm_widget_power_check(struct snd_soc_dapm_widget *w)
{
	if (w->power_checked)
		return w->new_power;

	if (w->force)
		return 1;
		w->new_power = 1;
	else
		return w->power_check(w);
		w->new_power = w->power_check(w);

	w->power_checked = true;

	return w->new_power;
}

/* Generic check to see if a widget should be powered.
@@ -1322,6 +1329,10 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)

	memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));

	list_for_each_entry(w, &card->widgets, list) {
		w->power_checked = false;
	}

	/* Check which widgets we need to power and store them in
	 * lists indicating if they should be powered up or down.  We
	 * only check widgets that have been flagged as dirty but note