#include <sound/soc-link.h>
 #include <sound/initval.h>
 
+static inline void snd_soc_dpcm_mutex_lock(struct snd_soc_pcm_runtime *rtd)
+{
+       mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
+}
+
+static inline void snd_soc_dpcm_mutex_unlock(struct snd_soc_pcm_runtime *rtd)
+{
+       mutex_unlock(&rtd->card->pcm_mutex);
+}
+
+#define snd_soc_dpcm_mutex_assert_held(rtd) \
+       lockdep_assert_held(&(rtd)->card->pcm_mutex)
+
+static inline void snd_soc_dpcm_stream_lock_irq(struct snd_soc_pcm_runtime *rtd,
+                                               int stream)
+{
+       snd_pcm_stream_lock_irq(snd_soc_dpcm_get_substream(rtd, stream));
+}
+
+static inline void snd_soc_dpcm_stream_unlock_irq(struct snd_soc_pcm_runtime *rtd,
+                                                 int stream)
+{
+       snd_pcm_stream_unlock_irq(snd_soc_dpcm_get_substream(rtd, stream));
+}
+
 #define DPCM_MAX_BE_USERS      8
 
 static inline const char *soc_cpu_dai_name(struct snd_soc_pcm_runtime *rtd)
        struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params;
        struct snd_soc_dpcm *dpcm;
        ssize_t offset = 0;
-       unsigned long flags;
 
        /* FE state */
        offset += scnprintf(buf + offset, size - offset,
                goto out;
        }
 
-       spin_lock_irqsave(&fe->card->dpcm_lock, flags);
        for_each_dpcm_be(fe, stream, dpcm) {
                struct snd_soc_pcm_runtime *be = dpcm->be;
                params = &dpcm->hw_params;
                                           params_channels(params),
                                           params_rate(params));
        }
-       spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 out:
        return offset;
 }
        if (!buf)
                return -ENOMEM;
 
+       snd_soc_dpcm_mutex_lock(fe);
        for_each_pcm_streams(stream)
                if (snd_soc_dai_stream_valid(asoc_rtd_to_cpu(fe, 0), stream))
                        offset += dpcm_show_state(fe, stream,
                                                  buf + offset,
                                                  out_count - offset);
+       snd_soc_dpcm_mutex_unlock(fe);
 
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, offset);
 
        struct snd_pcm_substream *substream =
                snd_soc_dpcm_get_substream(fe, stream);
 
-       snd_pcm_stream_lock_irq(substream);
+       snd_soc_dpcm_stream_lock_irq(fe, stream);
        if (state == SND_SOC_DPCM_UPDATE_NO && fe->dpcm[stream].trigger_pending) {
                dpcm_fe_dai_do_trigger(substream,
                                       fe->dpcm[stream].trigger_pending - 1);
                fe->dpcm[stream].trigger_pending = 0;
        }
        fe->dpcm[stream].runtime_update = state;
-       snd_pcm_stream_unlock_irq(substream);
+       snd_soc_dpcm_stream_unlock_irq(fe, stream);
 }
 
 static void dpcm_set_be_update_state(struct snd_soc_pcm_runtime *be,
        struct snd_soc_dai *dai;
        int i;
 
-       lockdep_assert_held(&rtd->card->pcm_mutex);
+       snd_soc_dpcm_mutex_assert_held(rtd);
 
        for_each_rtd_dais(rtd, i, dai)
                snd_soc_dai_action(dai, stream, action);
 {
        struct snd_soc_dpcm *dpcm;
 
+       snd_soc_dpcm_mutex_assert_held(fe);
+
        for_each_dpcm_be(fe, dir, dpcm) {
 
                struct snd_soc_pcm_runtime *be = dpcm->be;
        return ret;
 }
 
-static int soc_pcm_clean(struct snd_pcm_substream *substream, int rollback)
+static int soc_pcm_clean(struct snd_soc_pcm_runtime *rtd,
+                        struct snd_pcm_substream *substream, int rollback)
 {
-       struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
        struct snd_soc_component *component;
        struct snd_soc_dai *dai;
        int i;
 
-       mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
+       snd_soc_dpcm_mutex_assert_held(rtd);
 
        if (!rollback)
                snd_soc_runtime_deactivate(rtd, substream->stream);
 
        soc_pcm_components_close(substream, rollback);
 
-
-       mutex_unlock(&rtd->card->pcm_mutex);
-
        snd_soc_pcm_component_pm_runtime_put(rtd, substream, rollback);
 
        for_each_rtd_components(rtd, i, component)
  * freed here. The cpu DAI, codec DAI, machine and components are also
  * shutdown.
  */
+static int __soc_pcm_close(struct snd_soc_pcm_runtime *rtd,
+                          struct snd_pcm_substream *substream)
+{
+       return soc_pcm_clean(rtd, substream, 0);
+}
+
+/* PCM close ops for non-DPCM streams */
 static int soc_pcm_close(struct snd_pcm_substream *substream)
 {
-       return soc_pcm_clean(substream, 0);
+       struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+       snd_soc_dpcm_mutex_lock(rtd);
+       soc_pcm_clean(rtd, substream, 0);
+       snd_soc_dpcm_mutex_unlock(rtd);
+       return 0;
 }
 
 static int soc_hw_sanity_check(struct snd_pcm_substream *substream)
  * then initialized and any private data can be allocated. This also calls
  * startup for the cpu DAI, component, machine and codec DAI.
  */
-static int soc_pcm_open(struct snd_pcm_substream *substream)
+static int __soc_pcm_open(struct snd_soc_pcm_runtime *rtd,
+                         struct snd_pcm_substream *substream)
 {
-       struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
        struct snd_soc_component *component;
        struct snd_soc_dai *dai;
        int i, ret = 0;
 
+       snd_soc_dpcm_mutex_assert_held(rtd);
+
        for_each_rtd_components(rtd, i, component)
                pinctrl_pm_select_default_state(component->dev);
 
        ret = snd_soc_pcm_component_pm_runtime_get(rtd, substream);
        if (ret < 0)
-               goto pm_err;
-
-       mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
+               goto err;
 
        ret = soc_pcm_components_open(substream);
        if (ret < 0)
        snd_soc_runtime_activate(rtd, substream->stream);
        ret = 0;
 err:
-       mutex_unlock(&rtd->card->pcm_mutex);
-pm_err:
        if (ret < 0) {
-               soc_pcm_clean(substream, 1);
+               soc_pcm_clean(rtd, substream, 1);
                dev_err(rtd->dev, "%s() failed (%d)", __func__, ret);
        }
 
        return ret;
 }
 
+/* PCM open ops for non-DPCM streams */
+static int soc_pcm_open(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+       int ret;
+
+       snd_soc_dpcm_mutex_lock(rtd);
+       ret = __soc_pcm_open(rtd, substream);
+       snd_soc_dpcm_mutex_unlock(rtd);
+       return ret;
+}
+
 static void codec2codec_close_delayed_work(struct snd_soc_pcm_runtime *rtd)
 {
        /*
  * rate, etc.  This function is non atomic and can be called multiple times,
  * it can refer to the runtime info.
  */
-static int soc_pcm_prepare(struct snd_pcm_substream *substream)
+static int __soc_pcm_prepare(struct snd_soc_pcm_runtime *rtd,
+                            struct snd_pcm_substream *substream)
 {
-       struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
        struct snd_soc_dai *dai;
        int i, ret = 0;
 
-       mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
+       snd_soc_dpcm_mutex_assert_held(rtd);
 
        ret = snd_soc_link_prepare(substream);
        if (ret < 0)
                snd_soc_dai_digital_mute(dai, 0, substream->stream);
 
 out:
-       mutex_unlock(&rtd->card->pcm_mutex);
-
        if (ret < 0)
                dev_err(rtd->dev, "ASoC: %s() failed (%d)\n", __func__, ret);
 
        return ret;
 }
 
+/* PCM prepare ops for non-DPCM streams */
+static int soc_pcm_prepare(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+       int ret;
+
+       snd_soc_dpcm_mutex_lock(rtd);
+       ret = __soc_pcm_prepare(rtd, substream);
+       snd_soc_dpcm_mutex_unlock(rtd);
+       return ret;
+}
+
 static void soc_pcm_codec_params_fixup(struct snd_pcm_hw_params *params,
                                       unsigned int mask)
 {
        interval->max = channels;
 }
 
-static int soc_pcm_hw_clean(struct snd_pcm_substream *substream, int rollback)
+static int soc_pcm_hw_clean(struct snd_soc_pcm_runtime *rtd,
+                           struct snd_pcm_substream *substream, int rollback)
 {
-       struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
        struct snd_soc_dai *dai;
        int i;
 
-       mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
+       snd_soc_dpcm_mutex_assert_held(rtd);
 
        /* clear the corresponding DAIs parameters when going to be inactive */
        for_each_rtd_dais(rtd, i, dai) {
                if (snd_soc_dai_stream_valid(dai, substream->stream))
                        snd_soc_dai_hw_free(dai, substream, rollback);
 
-       mutex_unlock(&rtd->card->pcm_mutex);
        return 0;
 }
 
 /*
  * Frees resources allocated by hw_params, can be called multiple times
  */
+static int __soc_pcm_hw_free(struct snd_soc_pcm_runtime *rtd,
+                            struct snd_pcm_substream *substream)
+{
+       return soc_pcm_hw_clean(rtd, substream, 0);
+}
+
+/* hw_free PCM ops for non-DPCM streams */
 static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
 {
-       return soc_pcm_hw_clean(substream, 0);
+       struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+       int ret;
+
+       snd_soc_dpcm_mutex_lock(rtd);
+       ret = __soc_pcm_hw_free(rtd, substream);
+       snd_soc_dpcm_mutex_unlock(rtd);
+       return ret;
 }
 
 /*
  * function can also be called multiple times and can allocate buffers
  * (using snd_pcm_lib_* ). It's non-atomic.
  */
-static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *params)
+static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
+                              struct snd_pcm_substream *substream,
+                              struct snd_pcm_hw_params *params)
 {
-       struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
        struct snd_soc_dai *cpu_dai;
        struct snd_soc_dai *codec_dai;
        int i, ret = 0;
 
-       mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
+       snd_soc_dpcm_mutex_assert_held(rtd);
 
        ret = soc_pcm_params_symmetry(substream, params);
        if (ret)
 
        ret = snd_soc_pcm_component_hw_params(substream, params);
 out:
-       mutex_unlock(&rtd->card->pcm_mutex);
-
        if (ret < 0) {
-               soc_pcm_hw_clean(substream, 1);
+               soc_pcm_hw_clean(rtd, substream, 1);
                dev_err(rtd->dev, "ASoC: %s() failed (%d)\n", __func__, ret);
        }
 
        return ret;
 }
 
+/* hw_params PCM ops for non-DPCM streams */
+static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
+                            struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+       int ret;
+
+       snd_soc_dpcm_mutex_lock(rtd);
+       ret = __soc_pcm_hw_params(rtd, substream, params);
+       snd_soc_dpcm_mutex_unlock(rtd);
+       return ret;
+}
+
 static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
        struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
        struct snd_pcm_substream *fe_substream;
        struct snd_pcm_substream *be_substream;
        struct snd_soc_dpcm *dpcm;
-       unsigned long flags;
+
+       snd_soc_dpcm_mutex_assert_held(fe);
 
        /* only add new dpcms */
        for_each_dpcm_be(fe, stream, dpcm) {
        dpcm->fe = fe;
        be->dpcm[stream].runtime = fe->dpcm[stream].runtime;
        dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW;
-       spin_lock_irqsave(&fe->card->dpcm_lock, flags);
+       snd_soc_dpcm_stream_lock_irq(fe, stream);
        list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients);
        list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients);
-       spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
+       snd_soc_dpcm_stream_unlock_irq(fe, stream);
 
        dev_dbg(fe->dev, "connected new DPCM %s path %s %s %s\n",
                        stream ? "capture" : "playback",  fe->dai_link->name,
 void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
 {
        struct snd_soc_dpcm *dpcm, *d;
-       unsigned long flags;
 
+       snd_soc_dpcm_mutex_assert_held(fe);
+
+       snd_soc_dpcm_stream_lock_irq(fe, stream);
        for_each_dpcm_be_safe(fe, stream, dpcm, d) {
                dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n",
                                stream ? "capture" : "playback",
 
                dpcm_remove_debugfs_state(dpcm);
 
-               spin_lock_irqsave(&fe->card->dpcm_lock, flags);
                list_del(&dpcm->list_be);
                list_del(&dpcm->list_fe);
-               spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
                kfree(dpcm);
        }
+       snd_soc_dpcm_stream_unlock_irq(fe, stream);
 }
 
 /* get BE for DAI widget and stream */
 void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream)
 {
        struct snd_soc_dpcm *dpcm;
-       unsigned long flags;
 
-       spin_lock_irqsave(&fe->card->dpcm_lock, flags);
        for_each_dpcm_be(fe, stream, dpcm)
                dpcm_set_be_update_state(dpcm->be, stream, SND_SOC_DPCM_UPDATE_NO);
-       spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 }
 
 void dpcm_be_dai_stop(struct snd_soc_pcm_runtime *fe, int stream,
                                continue;
 
                        if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) {
-                               soc_pcm_hw_free(be_substream);
+                               __soc_pcm_hw_free(be, be_substream);
                                be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
                        }
                }
 
-               soc_pcm_close(be_substream);
+               __soc_pcm_close(be, be_substream);
                be_substream->runtime = NULL;
                be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
        }
                        stream ? "capture" : "playback", be->dai_link->name);
 
                be_substream->runtime = be->dpcm[stream].runtime;
-               err = soc_pcm_open(be_substream);
+               err = __soc_pcm_open(be, be_substream);
                if (err < 0) {
                        be->dpcm[stream].users--;
                        if (be->dpcm[stream].users < 0)
        dev_dbg(fe->dev, "ASoC: open FE %s\n", fe->dai_link->name);
 
        /* start the DAI frontend */
-       ret = soc_pcm_open(fe_substream);
+       ret = __soc_pcm_open(fe, fe_substream);
        if (ret < 0)
                goto unwind;
 
        struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream);
        int stream = substream->stream;
 
+       snd_soc_dpcm_mutex_assert_held(fe);
+
        dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
 
        /* shutdown the BEs */
        dev_dbg(fe->dev, "ASoC: close FE %s\n", fe->dai_link->name);
 
        /* now shutdown the frontend */
-       soc_pcm_close(substream);
+       __soc_pcm_close(fe, substream);
 
        /* run the stream stop event */
        dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
                dev_dbg(be->dev, "ASoC: hw_free BE %s\n",
                        be->dai_link->name);
 
-               soc_pcm_hw_free(be_substream);
+               __soc_pcm_hw_free(be, be_substream);
 
                be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
        }
        struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream);
        int stream = substream->stream;
 
-       mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
+       snd_soc_dpcm_mutex_lock(fe);
        dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
 
        dev_dbg(fe->dev, "ASoC: hw_free FE %s\n", fe->dai_link->name);
 
        /* call hw_free on the frontend */
-       soc_pcm_hw_free(substream);
+       soc_pcm_hw_clean(fe, substream, 0);
 
        /* only hw_params backends that are either sinks or sources
         * to this frontend DAI */
        fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
        dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
 
-       mutex_unlock(&fe->card->mutex);
+       snd_soc_dpcm_mutex_unlock(fe);
        return 0;
 }
 
                dev_dbg(be->dev, "ASoC: hw_params BE %s\n",
                        be->dai_link->name);
 
-               ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params);
+               ret = __soc_pcm_hw_params(be, be_substream, &dpcm->hw_params);
                if (ret < 0)
                        goto unwind;
 
                   (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
                        continue;
 
-               soc_pcm_hw_free(be_substream);
+               __soc_pcm_hw_free(be, be_substream);
        }
 
        return ret;
        struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream);
        int ret, stream = substream->stream;
 
-       mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
+       snd_soc_dpcm_mutex_lock(fe);
        dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
 
        memcpy(&fe->dpcm[stream].hw_params, params,
                        params_channels(params), params_format(params));
 
        /* call hw_params on the frontend */
-       ret = soc_pcm_hw_params(substream, params);
+       ret = __soc_pcm_hw_params(fe, substream, params);
        if (ret < 0)
                dpcm_be_dai_hw_free(fe, stream);
        else
 
 out:
        dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
-       mutex_unlock(&fe->card->mutex);
+       snd_soc_dpcm_mutex_unlock(fe);
 
        if (ret < 0)
                dev_err(fe->dev, "ASoC: %s failed (%d)\n", __func__, ret);
                dev_dbg(be->dev, "ASoC: prepare BE %s\n",
                        be->dai_link->name);
 
-               ret = soc_pcm_prepare(be_substream);
+               ret = __soc_pcm_prepare(be, be_substream);
                if (ret < 0)
                        break;
 
        struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream);
        int stream = substream->stream, ret = 0;
 
-       mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
+       snd_soc_dpcm_mutex_lock(fe);
 
        dev_dbg(fe->dev, "ASoC: prepare FE %s\n", fe->dai_link->name);
 
                goto out;
 
        /* call prepare on the frontend */
-       ret = soc_pcm_prepare(substream);
+       ret = __soc_pcm_prepare(fe, substream);
        if (ret < 0)
                goto out;
 
 
 out:
        dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
-       mutex_unlock(&fe->card->mutex);
+       snd_soc_dpcm_mutex_unlock(fe);
 
        if (ret < 0)
                dev_err(fe->dev, "ASoC: %s() failed (%d)\n", __func__, ret);
        struct snd_soc_dpcm *dpcm;
        enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
        int ret = 0;
-       unsigned long flags;
 
        dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n",
                        stream ? "capture" : "playback", fe->dai_link->name);
        dpcm_be_dai_shutdown(fe, stream);
 disconnect:
        /* disconnect any pending BEs */
-       spin_lock_irqsave(&fe->card->dpcm_lock, flags);
        for_each_dpcm_be(fe, stream, dpcm) {
                struct snd_soc_pcm_runtime *be = dpcm->be;
 
                        be->dpcm[stream].state == SND_SOC_DPCM_STATE_NEW)
                                dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
        }
-       spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 
        if (ret < 0)
                dev_err(fe->dev, "ASoC: %s() failed (%d)\n", __func__, ret);
        struct snd_soc_pcm_runtime *fe;
        int ret = 0;
 
-       mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
+       mutex_lock_nested(&card->pcm_mutex, card->pcm_subclass);
        /* shutdown all old paths first */
        for_each_card_rtds(card, fe) {
                ret = soc_dpcm_fe_runtime_update(fe, 0);
        }
 
 out:
-       mutex_unlock(&card->mutex);
+       mutex_unlock(&card->pcm_mutex);
        return ret;
 }
 EXPORT_SYMBOL_GPL(snd_soc_dpcm_runtime_update);
        struct snd_soc_dpcm *dpcm;
        int stream = fe_substream->stream;
 
+       snd_soc_dpcm_mutex_assert_held(fe);
+
        /* mark FE's links ready to prune */
        for_each_dpcm_be(fe, stream, dpcm)
                dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
        struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(fe_substream);
        int ret;
 
-       mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
+       snd_soc_dpcm_mutex_lock(fe);
        ret = dpcm_fe_dai_shutdown(fe_substream);
 
        dpcm_fe_dai_cleanup(fe_substream);
 
-       mutex_unlock(&fe->card->mutex);
+       snd_soc_dpcm_mutex_unlock(fe);
        return ret;
 }
 
        int ret;
        int stream = fe_substream->stream;
 
-       mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
+       snd_soc_dpcm_mutex_lock(fe);
        fe->dpcm[stream].runtime = fe_substream->runtime;
 
        ret = dpcm_path_get(fe, stream, &list);
        dpcm_clear_pending_state(fe, stream);
        dpcm_path_put(&list);
 open_end:
-       mutex_unlock(&fe->card->mutex);
+       snd_soc_dpcm_mutex_unlock(fe);
        return ret;
 }
 
        struct snd_soc_dpcm *dpcm;
        int state;
        int ret = 1;
-       unsigned long flags;
        int i;
 
-       spin_lock_irqsave(&fe->card->dpcm_lock, flags);
        for_each_dpcm_fe(be, stream, dpcm) {
 
                if (dpcm->fe == fe)
                        }
                }
        }
-       spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 
        /* it's safe to do this BE DAI */
        return ret;