diff --git a/Documentation/sound/designs/compress-offload.rst b/Documentation/sound/designs/compress-offload.rst
index 935f325dbc77..205cadcabe70 100644
--- a/Documentation/sound/designs/compress-offload.rst
+++ b/Documentation/sound/designs/compress-offload.rst
@@ -256,32 +256,32 @@ Gapless Playback SM
 For Gapless, we move from running state to partial drain and back, along
 with setting of meta_data and signalling for next track ::
 
-
-                                        +----------+
-                compr_drain_notify()    |          |
-              +------------------------>|  RUNNING |
-              |                         |          |
-              |                         +----------+
-              |                              |
-              |                              |
-              |                              | compr_next_track()
-              |                              |
-              |                              V
-              |                         +----------+
-              |                         |          |
-              |                         |NEXT_TRACK|
-              |                         |          |
-              |                         +----------+
-              |                              |
-              |                              |
-              |                              | compr_partial_drain()
-              |                              |
-              |                              V
-              |                         +----------+
-              |                         |          |
-              +------------------------ | PARTIAL_ |
-                                        |  DRAIN   |
-                                        +----------+
+                            +----------+
+     compr_drain_notify()   |          | compr_set_params() iff next-track set.
+  +------------------------>|  RUNNING |----------------------+
+  |                         |          |                      |
+  |                         +----------+                      |
+  |                              |                            |
+  |                              |                            |
+  |                              | compr_next_track()         |
+  |                              |                            V
+  |                              V                            |
+  |                         +----------+                      |
+  |                         |          |                      |
+  |                         |NEXT_TRACK|                      |
+  |                         |          |                      |
+  |                         +----------+                      |
+  |                              |                            |
+  |                              +----------------------------+
+  |                              |
+  |                              | compr_partial_drain()
+  |                              |
+  |                              V
+  |                         +----------+
+  |                         |          |
+  +------------------------ | PARTIAL_ |
+                            |  DRAIN   |
+                            +----------+
 
 Not supported
 =============
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index 243acad89fd3..fe67228e74b3 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -294,6 +294,9 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf,
 	case SNDRV_PCM_STATE_SETUP:
 	case SNDRV_PCM_STATE_PREPARED:
 	case SNDRV_PCM_STATE_RUNNING:
+		/* Make sure next track params are set before writing new data */
+		if (stream->next_track)
+			return -EPERM;
 		break;
 	default:
 		mutex_unlock(&stream->device->lock);
@@ -589,7 +592,8 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
 	struct snd_compr_params *params;
 	int retval;
 
-	if (stream->runtime->state == SNDRV_PCM_STATE_OPEN) {
+	if (stream->runtime->state == SNDRV_PCM_STATE_OPEN ||
+	    (stream->runtime->state == SNDRV_PCM_STATE_RUNNING && stream->next_track)) {
 		/*
 		 * we should allow parameter change only when stream has been
 		 * opened not in other cases
@@ -615,7 +619,8 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
 		stream->metadata_set = false;
 		stream->next_track = false;
 
-		stream->runtime->state = SNDRV_PCM_STATE_SETUP;
+		if (stream->runtime->state == SNDRV_PCM_STATE_OPEN)
+			stream->runtime->state = SNDRV_PCM_STATE_SETUP;
 	} else {
 		return -EPERM;
 	}
@@ -956,7 +961,6 @@ static int snd_compr_partial_drain(struct snd_compr_stream *stream)
 		return retval;
 	}
 
-	stream->next_track = false;
 	return snd_compress_wait_for_drain(stream);
 }
 
