__be32 words_written[2];        /* total words written (64 bit) */
 };
 
+struct wm_adsp_compr;
+
 struct wm_adsp_compr_buf {
        struct wm_adsp *dsp;
+       struct wm_adsp_compr *compr;
 
        struct wm_adsp_buffer_region *regions;
        u32 host_buf_ptr;
                return -EINVAL;
 
        compr->buf = compr->dsp->buffer;
+       compr->buf->compr = compr;
 
        return 0;
 }
 
+static void wm_adsp_compr_detach(struct wm_adsp_compr *compr)
+{
+       if (!compr)
+               return;
+
+       /* Wake the poll so it can see buffer is no longer attached */
+       if (compr->stream)
+               snd_compr_fragment_elapsed(compr->stream);
+
+       if (wm_adsp_compr_attached(compr)) {
+               compr->buf->compr = NULL;
+               compr->buf = NULL;
+       }
+}
+
 int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream)
 {
        struct wm_adsp_compr *compr;
 
        mutex_lock(&dsp->pwr_lock);
 
+       wm_adsp_compr_detach(compr);
        dsp->compr = NULL;
 
        kfree(compr->raw_buf);
 static int wm_adsp_buffer_free(struct wm_adsp *dsp)
 {
        if (dsp->buffer) {
+               wm_adsp_compr_detach(dsp->buffer->compr);
+
                kfree(dsp->buffer->regions);
                kfree(dsp->buffer);