diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-10-03 17:36:57 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-10-04 11:50:21 -0400 |
commit | fe4fda5d8f28d06ae8f1482f4bde8a83be16e44b (patch) | |
tree | 0c8352c5495db26e53b695f356be424f0ba75bbe | |
parent | db432b414e20b7218bbd91654d7be9c524a4337a (diff) |
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>
-rw-r--r-- | sound/soc/soc-dapm.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 9d6bb33e6094..214a709128d2 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -1215,6 +1215,21 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) | |||
1215 | } | 1215 | } |
1216 | } | 1216 | } |
1217 | 1217 | ||
1218 | static void dapm_widget_set_peer_power(struct snd_soc_dapm_widget *peer, | ||
1219 | bool power, bool connect) | ||
1220 | { | ||
1221 | /* If a connection is being made or broken then that update | ||
1222 | * will have marked the peer dirty, otherwise the widgets are | ||
1223 | * not connected and this update has no impact. */ | ||
1224 | if (!connect) | ||
1225 | return; | ||
1226 | |||
1227 | /* If the peer is already in the state we're moving to then we | ||
1228 | * won't have an impact on it. */ | ||
1229 | if (power != peer->power) | ||
1230 | dapm_mark_dirty(peer); | ||
1231 | } | ||
1232 | |||
1218 | static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power, | 1233 | static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power, |
1219 | struct list_head *up_list, | 1234 | struct list_head *up_list, |
1220 | struct list_head *down_list) | 1235 | struct list_head *down_list) |
@@ -1227,19 +1242,18 @@ static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power, | |||
1227 | trace_snd_soc_dapm_widget_power(w, power); | 1242 | trace_snd_soc_dapm_widget_power(w, power); |
1228 | 1243 | ||
1229 | /* If we changed our power state perhaps our neigbours changed | 1244 | /* If we changed our power state perhaps our neigbours changed |
1230 | * also. We're not yet smart enough to update relevant | 1245 | * also. |
1231 | * neighbours when we change the state of a widget, this acts | ||
1232 | * as a proxy for that. It will notify more neighbours than | ||
1233 | * is ideal. | ||
1234 | */ | 1246 | */ |
1235 | list_for_each_entry(path, &w->sources, list_sink) { | 1247 | list_for_each_entry(path, &w->sources, list_sink) { |
1236 | if (path->source) { | 1248 | if (path->source) { |
1237 | dapm_mark_dirty(path->source); | 1249 | dapm_widget_set_peer_power(path->source, power, |
1250 | path->connect); | ||
1238 | } | 1251 | } |
1239 | } | 1252 | } |
1240 | list_for_each_entry(path, &w->sinks, list_source) { | 1253 | list_for_each_entry(path, &w->sinks, list_source) { |
1241 | if (path->sink) { | 1254 | if (path->sink) { |
1242 | dapm_mark_dirty(path->sink); | 1255 | dapm_widget_set_peer_power(path->sink, power, |
1256 | path->connect); | ||
1243 | } | 1257 | } |
1244 | } | 1258 | } |
1245 | 1259 | ||