ASoC: dapm: Reduce number of checked paths in dapm_widget_in_card_paths()
authorLars-Peter Clausen <lars@metafoo.de>
Mon, 20 Oct 2014 17:36:33 +0000 (19:36 +0200)
committerMark Brown <broonie@kernel.org>
Wed, 22 Oct 2014 11:02:33 +0000 (12:02 +0100)
Each widget has a list of all the paths that it is connected to. There is no
need to iterate over all paths when we are only interested in the paths of a
specific widget.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/soc-dapm.c

index 39f992bc2b6adf1d36dd9647b860c839edf4087b..2c4bfdbae88ff794c310e660bc21cd9cc58c8cae 100644 (file)
@@ -3788,35 +3788,54 @@ int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
 }
 EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
 
+/**
+ * dapm_is_external_path() - Checks if a path is a external path
+ * @card: The card the path belongs to
+ * @path: The path to check
+ *
+ * Returns true if the path is either between two different DAPM contexts or
+ * between two external pins of the same DAPM context. Otherwise returns
+ * false.
+ */
+static bool dapm_is_external_path(struct snd_soc_card *card,
+       struct snd_soc_dapm_path *path)
+{
+       dev_dbg(card->dev,
+               "... Path %s(id:%d dapm:%p) - %s(id:%d dapm:%p)\n",
+               path->source->name, path->source->id, path->source->dapm,
+               path->sink->name, path->sink->id, path->sink->dapm);
+
+       /* Connection between two different DAPM contexts */
+       if (path->source->dapm != path->sink->dapm)
+               return true;
+
+       /* Loopback connection from external pin to external pin */
+       if (path->sink->id == snd_soc_dapm_input) {
+               switch (path->source->id) {
+               case snd_soc_dapm_output:
+               case snd_soc_dapm_micbias:
+                       return true;
+               default:
+                       break;
+               }
+       }
+
+       return false;
+}
+
 static bool snd_soc_dapm_widget_in_card_paths(struct snd_soc_card *card,
                                              struct snd_soc_dapm_widget *w)
 {
        struct snd_soc_dapm_path *p;
 
-       list_for_each_entry(p, &card->paths, list) {
-               if ((p->source == w) || (p->sink == w)) {
-                       dev_dbg(card->dev,
-                           "... Path %s(id:%d dapm:%p) - %s(id:%d dapm:%p)\n",
-                           p->source->name, p->source->id, p->source->dapm,
-                           p->sink->name, p->sink->id, p->sink->dapm);
+       list_for_each_entry(p, &w->sources, list_sink) {
+               if (dapm_is_external_path(card, p))
+                       return true;
+       }
 
-                       /* Connected to something other than the codec */
-                       if (p->source->dapm != p->sink->dapm)
-                               return true;
-                       /*
-                        * Loopback connection from codec external pin to
-                        * codec external pin
-                        */
-                       if (p->sink->id == snd_soc_dapm_input) {
-                               switch (p->source->id) {
-                               case snd_soc_dapm_output:
-                               case snd_soc_dapm_micbias:
-                                       return true;
-                               default:
-                                       break;
-                               }
-                       }
-               }
+       list_for_each_entry(p, &w->sinks, list_source) {
+               if (dapm_is_external_path(card, p))
+                       return true;
        }
 
        return false;