struct snd_soc_pcm_runtime *be;
        struct snd_soc_dpcm *dpcm;
        int ret = 0;
+       unsigned long flags;
+       enum snd_soc_dpcm_state state;
 
        for_each_dpcm_be(fe, stream, dpcm) {
                struct snd_pcm_substream *be_substream;
 
                switch (cmd) {
                case SNDRV_PCM_TRIGGER_START:
+                       spin_lock_irqsave(&fe->card->dpcm_lock, flags);
                        if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
                            (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) &&
-                           (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED))
+                           (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) {
+                               spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
                                continue;
+                       }
+                       state = be->dpcm[stream].state;
+                       be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
+                       spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 
                        ret = soc_pcm_trigger(be_substream, cmd);
-                       if (ret)
+                       if (ret) {
+                               spin_lock_irqsave(&fe->card->dpcm_lock, flags);
+                               be->dpcm[stream].state = state;
+                               spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
                                goto end;
+                       }
 
-                       be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
                        break;
                case SNDRV_PCM_TRIGGER_RESUME:
-                       if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND))
+                       spin_lock_irqsave(&fe->card->dpcm_lock, flags);
+                       if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND) {
+                               spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
                                continue;
+                       }
+
+                       state = be->dpcm[stream].state;
+                       be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
+                       spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 
                        ret = soc_pcm_trigger(be_substream, cmd);
-                       if (ret)
+                       if (ret) {
+                               spin_lock_irqsave(&fe->card->dpcm_lock, flags);
+                               be->dpcm[stream].state = state;
+                               spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
                                goto end;
+                       }
 
-                       be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
                        break;
                case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-                       if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED))
+                       spin_lock_irqsave(&fe->card->dpcm_lock, flags);
+                       if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED) {
+                               spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
                                continue;
+                       }
+
+                       state = be->dpcm[stream].state;
+                       be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
+                       spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 
                        ret = soc_pcm_trigger(be_substream, cmd);
-                       if (ret)
+                       if (ret) {
+                               spin_lock_irqsave(&fe->card->dpcm_lock, flags);
+                               be->dpcm[stream].state = state;
+                               spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
                                goto end;
+                       }
 
-                       be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
                        break;
                case SNDRV_PCM_TRIGGER_STOP:
+                       spin_lock_irqsave(&fe->card->dpcm_lock, flags);
                        if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) &&
-                           (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED))
+                           (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) {
+                               spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
                                continue;
+                       }
+                       spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 
                        if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
                                continue;
 
+                       spin_lock_irqsave(&fe->card->dpcm_lock, flags);
+                       state = be->dpcm[stream].state;
+                       be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
+                       spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
+
                        ret = soc_pcm_trigger(be_substream, cmd);
-                       if (ret)
+                       if (ret) {
+                               spin_lock_irqsave(&fe->card->dpcm_lock, flags);
+                               be->dpcm[stream].state = state;
+                               spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
                                goto end;
+                       }
 
-                       be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
                        break;
                case SNDRV_PCM_TRIGGER_SUSPEND:
-                       if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
+                       spin_lock_irqsave(&fe->card->dpcm_lock, flags);
+                       if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) {
+                               spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
                                continue;
+                       }
+                       spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 
                        if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
                                continue;
 
+                       spin_lock_irqsave(&fe->card->dpcm_lock, flags);
+                       state = be->dpcm[stream].state;
+                       be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
+                       spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
+
                        ret = soc_pcm_trigger(be_substream, cmd);
-                       if (ret)
+                       if (ret) {
+                               spin_lock_irqsave(&fe->card->dpcm_lock, flags);
+                               be->dpcm[stream].state = state;
+                               spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
                                goto end;
+                       }
 
-                       be->dpcm[stream].state = SND_SOC_DPCM_STATE_SUSPEND;
                        break;
                case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-                       if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
+                       spin_lock_irqsave(&fe->card->dpcm_lock, flags);
+                       if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) {
+                               spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
                                continue;
+                       }
+                       spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 
                        if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
                                continue;
 
+                       spin_lock_irqsave(&fe->card->dpcm_lock, flags);
+                       state = be->dpcm[stream].state;
+                       be->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
+                       spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
+
                        ret = soc_pcm_trigger(be_substream, cmd);
-                       if (ret)
+                       if (ret) {
+                               spin_lock_irqsave(&fe->card->dpcm_lock, flags);
+                               be->dpcm[stream].state = state;
+                               spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
                                goto end;
+                       }
 
-                       be->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
                        break;
                }
        }