SND_SOC_RBTREE_COMPRESSION
 };
 
+enum snd_soc_pcm_subclass {
+       SND_SOC_PCM_CLASS_PCM   = 0,
+       SND_SOC_PCM_CLASS_BE    = 1,
+};
+
 int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
                             unsigned int freq, int dir);
 int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
        struct device dev;
        struct snd_soc_card *card;
        struct snd_soc_dai_link *dai_link;
+       struct mutex pcm_mutex;
+       enum snd_soc_pcm_subclass pcm_subclass;
+       struct snd_pcm_ops ops;
 
        unsigned int complete:1;
        unsigned int dev_registered:1;
 
        struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver;
        int ret = 0;
 
-       mutex_lock(&pcm_mutex);
+       mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
 
        /* startup the audio subsystem */
        if (cpu_dai->driver->ops->startup) {
        cpu_dai->active++;
        codec_dai->active++;
        rtd->codec->active++;
-       mutex_unlock(&pcm_mutex);
+       mutex_unlock(&rtd->pcm_mutex);
        return 0;
 
 config_err:
        if (cpu_dai->driver->ops->shutdown)
                cpu_dai->driver->ops->shutdown(substream, cpu_dai);
 out:
-       mutex_unlock(&pcm_mutex);
+       mutex_unlock(&rtd->pcm_mutex);
        return ret;
 }
 
                        container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
 
-       mutex_lock(&pcm_mutex);
+       mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
 
        pr_debug("pop wq checking: %s status: %s waiting: %s\n",
                 codec_dai->driver->playback.stream_name,
                        SND_SOC_DAPM_STREAM_STOP);
        }
 
-       mutex_unlock(&pcm_mutex);
+       mutex_unlock(&rtd->pcm_mutex);
 }
 
 /*
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
        struct snd_soc_codec *codec = rtd->codec;
 
-       mutex_lock(&pcm_mutex);
+       mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                cpu_dai->playback_active--;
                        SND_SOC_DAPM_STREAM_STOP);
        }
 
-       mutex_unlock(&pcm_mutex);
+       mutex_unlock(&rtd->pcm_mutex);
        return 0;
 }
 
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
        int ret = 0;
 
-       mutex_lock(&pcm_mutex);
+       mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
 
        if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) {
                ret = rtd->dai_link->ops->prepare(substream);
        snd_soc_dai_digital_mute(codec_dai, 0);
 
 out:
-       mutex_unlock(&pcm_mutex);
+       mutex_unlock(&rtd->pcm_mutex);
        return ret;
 }
 
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
        int ret = 0;
 
-       mutex_lock(&pcm_mutex);
+       mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
 
        if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) {
                ret = rtd->dai_link->ops->hw_params(substream, params);
        rtd->rate = params_rate(params);
 
 out:
-       mutex_unlock(&pcm_mutex);
+       mutex_unlock(&rtd->pcm_mutex);
        return ret;
 
 platform_err:
        if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
                rtd->dai_link->ops->hw_free(substream);
 
-       mutex_unlock(&pcm_mutex);
+       mutex_unlock(&rtd->pcm_mutex);
        return ret;
 }
 
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
        struct snd_soc_codec *codec = rtd->codec;
 
-       mutex_lock(&pcm_mutex);
+       mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
 
        /* apply codec digital mute */
        if (!codec->active)
        if (cpu_dai->driver->ops->hw_free)
                cpu_dai->driver->ops->hw_free(substream, cpu_dai);
 
-       mutex_unlock(&pcm_mutex);
+       mutex_unlock(&rtd->pcm_mutex);
        return 0;
 }