aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc-dapm.h7
-rw-r--r--sound/soc/soc-dapm.c39
2 files changed, 46 insertions, 0 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 96c5e0ec81d1..b9170e2bc5ab 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -593,6 +593,10 @@ struct snd_soc_dapm_update {
int val;
};
+struct snd_soc_dapm_wcache {
+ struct snd_soc_dapm_widget *widget;
+};
+
/* DAPM context */
struct snd_soc_dapm_context {
enum snd_soc_bias_level bias_level;
@@ -614,6 +618,9 @@ struct snd_soc_dapm_context {
int (*set_bias_level)(struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level);
+ struct snd_soc_dapm_wcache path_sink_cache;
+ struct snd_soc_dapm_wcache path_source_cache;
+
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_dapm;
#endif
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 63748526d630..10fb7087c405 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -572,6 +572,35 @@ static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm)
snd_soc_component_async_complete(dapm->component);
}
+static struct snd_soc_dapm_widget *
+dapm_wcache_lookup(struct snd_soc_dapm_wcache *wcache, const char *name)
+{
+ struct snd_soc_dapm_widget *w = wcache->widget;
+ struct list_head *wlist;
+ const int depth = 2;
+ int i = 0;
+
+ if (w) {
+ wlist = &w->dapm->card->widgets;
+
+ list_for_each_entry_from(w, wlist, list) {
+ if (!strcmp(name, w->name))
+ return w;
+
+ if (++i == depth)
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static inline void dapm_wcache_update(struct snd_soc_dapm_wcache *wcache,
+ struct snd_soc_dapm_widget *w)
+{
+ wcache->widget = w;
+}
+
/**
* snd_soc_dapm_force_bias_level() - Sets the DAPM bias level
* @dapm: The DAPM context for which to set the level
@@ -2610,6 +2639,12 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
source = route->source;
}
+ wsource = dapm_wcache_lookup(&dapm->path_source_cache, source);
+ wsink = dapm_wcache_lookup(&dapm->path_sink_cache, sink);
+
+ if (wsink && wsource)
+ goto skip_search;
+
/*
* find src and dest widgets over all widgets but favor a widget from
* current DAPM context
@@ -2650,6 +2685,10 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
return -ENODEV;
}
+skip_search:
+ dapm_wcache_update(&dapm->path_sink_cache, wsink);
+ dapm_wcache_update(&dapm->path_source_cache, wsource);
+
ret = snd_soc_dapm_add_path(dapm, wsource, wsink, route->control,
route->connected);
if (ret)