return ret;
 }
 
+static int sof_pcm_dsp_pcm_free(struct snd_pcm_substream *substream,
+                               struct snd_sof_dev *sdev,
+                               struct snd_sof_pcm *spcm)
+{
+       struct sof_ipc_stream stream;
+       struct sof_ipc_reply reply;
+       int ret;
+
+       stream.hdr.size = sizeof(stream);
+       stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_FREE;
+       stream.comp_id = spcm->stream[substream->stream].comp_id;
+
+       /* send IPC to the DSP */
+       ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
+                                sizeof(stream), &reply, sizeof(reply));
+       if (!ret)
+               spcm->prepared[substream->stream] = false;
+
+       return ret;
+}
+
 static int sof_pcm_hw_free(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
                snd_soc_rtdcom_lookup(rtd, DRV_NAME);
        struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
        struct snd_sof_pcm *spcm;
-       struct sof_ipc_stream stream;
-       struct sof_ipc_reply reply;
        int ret;
 
        /* nothing to do for BE */
        dev_dbg(sdev->dev, "pcm: free stream %d dir %d\n", spcm->pcm.pcm_id,
                substream->stream);
 
-       stream.hdr.size = sizeof(stream);
-       stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_FREE;
-       stream.comp_id = spcm->stream[substream->stream].comp_id;
-
-       /* send IPC to the DSP */
-       ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
-                                sizeof(stream), &reply, sizeof(reply));
+       ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
 
        snd_pcm_lib_free_pages(substream);
 
        if (ret < 0)
                dev_err(sdev->dev, "error: platform hw free failed\n");
 
-       spcm->prepared[substream->stream] = false;
-
        return ret;
 }
 
        ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
                                 sizeof(stream), &reply, sizeof(reply));
 
-       if (ret < 0 || !reset_hw_params)
-               return ret;
-
-       /*
-        * In case of stream is stopped, DSP must be reprogrammed upon
-        * restart, so free PCM here.
-        */
-       stream.hdr.size = sizeof(stream);
-       stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_FREE;
-       stream.comp_id = spcm->stream[substream->stream].comp_id;
-       spcm->prepared[substream->stream] = false;
+       if (!ret && reset_hw_params)
+               ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
 
-       /* send IPC to the DSP */
-       return sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
-                                 sizeof(stream), &reply, sizeof(reply));
+       return ret;
 }
 
 static snd_pcm_uframes_t sof_pcm_pointer(struct snd_pcm_substream *substream)