1
0
Fork 0

ASoC: Reduce the number of neigbours we mark dirty when updating power

If two widgets are not currently connected then there is no need to
propagate a power state change between them as we mark the affected
widgets when we change a connection. Similarly if a neighbour widget is
already in the state being set for the current widget then there is no
need to recheck.

On one system I tested this gave:

           Power    Path   Neighbour
Before:    114      1066   1327
After:     106      970    1186

which is an improvement, although relatively small.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
hifive-unleashed-5.1
Mark Brown 2011-10-03 22:36:57 +01:00
parent db432b414e
commit fe4fda5d8f
1 changed files with 20 additions and 6 deletions

View File

@ -1215,6 +1215,21 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
}
}
static void dapm_widget_set_peer_power(struct snd_soc_dapm_widget *peer,
bool power, bool connect)
{
/* If a connection is being made or broken then that update
* will have marked the peer dirty, otherwise the widgets are
* not connected and this update has no impact. */
if (!connect)
return;
/* If the peer is already in the state we're moving to then we
* won't have an impact on it. */
if (power != peer->power)
dapm_mark_dirty(peer);
}
static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power,
struct list_head *up_list,
struct list_head *down_list)
@ -1227,19 +1242,18 @@ static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power,
trace_snd_soc_dapm_widget_power(w, power);
/* If we changed our power state perhaps our neigbours changed
* also. We're not yet smart enough to update relevant
* neighbours when we change the state of a widget, this acts
* as a proxy for that. It will notify more neighbours than
* is ideal.
* also.
*/
list_for_each_entry(path, &w->sources, list_sink) {
if (path->source) {
dapm_mark_dirty(path->source);
dapm_widget_set_peer_power(path->source, power,
path->connect);
}
}
list_for_each_entry(path, &w->sinks, list_source) {
if (path->sink) {
dapm_mark_dirty(path->sink);
dapm_widget_set_peer_power(path->sink, power,
path->connect);
}
}