summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/soc/soc-dapm.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 9273216f22f..1dbc5f8cdc9 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -409,6 +409,12 @@ static inline void soc_widget_unlock(struct snd_soc_dapm_widget *w)
mutex_unlock(&w->platform->mutex);
}
+static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm)
+{
+ if (dapm->codec && dapm->codec->using_regmap)
+ regmap_async_complete(dapm->codec->control_data);
+}
+
static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w,
unsigned short reg, unsigned int mask, unsigned int value)
{
@@ -417,8 +423,9 @@ static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w,
int ret;
if (w->codec && w->codec->using_regmap) {
- ret = regmap_update_bits_check(w->codec->control_data,
- reg, mask, value, &change);
+ ret = regmap_update_bits_check_async(w->codec->control_data,
+ reg, mask, value,
+ &change);
if (ret != 0)
return ret;
} else {
@@ -1201,6 +1208,8 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
{
int ret;
+ soc_dapm_async_complete(w->dapm);
+
if (SND_SOC_DAPM_EVENT_ON(event)) {
if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) {
ret = regulator_allow_bypass(w->regulator, false);
@@ -1234,6 +1243,8 @@ int dapm_clock_event(struct snd_soc_dapm_widget *w,
if (!w->clk)
return -EIO;
+ soc_dapm_async_complete(w->dapm);
+
#ifdef CONFIG_HAVE_CLK
if (SND_SOC_DAPM_EVENT_ON(event)) {
return clk_prepare_enable(w->clk);
@@ -1426,6 +1437,7 @@ static void dapm_seq_check_event(struct snd_soc_card *card,
if (w->event && (w->event_flags & event)) {
pop_dbg(w->dapm->dev, card->pop_time, "pop test : %s %s\n",
w->name, ev_name);
+ soc_dapm_async_complete(w->dapm);
trace_snd_soc_dapm_widget_event_start(w, event);
ret = w->event(w, NULL, event);
trace_snd_soc_dapm_widget_event_done(w, event);
@@ -1498,6 +1510,7 @@ static void dapm_seq_run(struct snd_soc_card *card,
struct list_head *list, int event, bool power_up)
{
struct snd_soc_dapm_widget *w, *n;
+ struct snd_soc_dapm_context *d;
LIST_HEAD(pending);
int cur_sort = -1;
int cur_subseq = -1;
@@ -1528,6 +1541,9 @@ static void dapm_seq_run(struct snd_soc_card *card,
cur_subseq);
}
+ if (cur_dapm && w->dapm != cur_dapm)
+ soc_dapm_async_complete(cur_dapm);
+
INIT_LIST_HEAD(&pending);
cur_sort = -1;
cur_subseq = INT_MIN;
@@ -1586,6 +1602,10 @@ static void dapm_seq_run(struct snd_soc_card *card,
cur_dapm->seq_notifier(cur_dapm,
i, cur_subseq);
}
+
+ list_for_each_entry(d, &card->dapm_list, list) {
+ soc_dapm_async_complete(d);
+ }
}
static void dapm_widget_update(struct snd_soc_card *card)