diff --git a/drivers/staging/greybus/audio-gb-cmds.c b/drivers/staging/greybus/audio-gb-cmds.c
index 8a101286d7bee7f86554433de3674ba9b02cd6d1..d625f782b5132c9855ad2b50fccace98f9f4ef37 100644
--- a/drivers/staging/greybus/audio-gb-cmds.c
+++ b/drivers/staging/greybus/audio-gb-cmds.c
@@ -165,17 +165,8 @@ int gb_i2s_mgmt_setup(struct gb_connection *connection)
 
 	ret = gb_i2s_mgmt_set_samples_per_message(connection,
 						  CONFIG_SAMPLES_PER_MSG);
-	if (ret) {
+	if (ret)
 		pr_err("set_samples_per_msg failed: %d\n", ret);
-		goto free_get_cfg;
-	}
-
-	ret = gb_i2s_mgmt_activate_cport(connection,
-					 CONFIG_I2S_REMOTE_DATA_CPORT);
-	if (ret) {
-		pr_err("activate_cport failed: %d\n", ret);
-		goto free_get_cfg;
-	}
 
 free_get_cfg:
 	kfree(get_cfg);
diff --git a/drivers/staging/greybus/audio-pcm.c b/drivers/staging/greybus/audio-pcm.c
index 92436300b3ebffdd1c71c9bd57ea0c912fe67b03..8eb803a7a40a6d6e6154ec65320249121695576b 100644
--- a/drivers/staging/greybus/audio-pcm.c
+++ b/drivers/staging/greybus/audio-pcm.c
@@ -32,15 +32,33 @@ static void gb_pcm_work(struct work_struct *work)
 	struct snd_pcm_substream *substream = snd_dev->substream;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int stride, frames, oldptr;
-	int period_elapsed;
+	int period_elapsed, ret;
 	char *address;
 	long len;
 
 	if (!snd_dev)
 		return;
 
-	if (!atomic_read(&snd_dev->running))
+	if (!atomic_read(&snd_dev->running)) {
+		if (snd_dev->cport_active) {
+			ret = gb_i2s_mgmt_deactivate_cport(
+						snd_dev->mgmt_connection,
+						CONFIG_I2S_REMOTE_DATA_CPORT);
+			if (ret) /* XXX Do what else with failure? */
+				pr_err("deactivate_cport failed: %d\n", ret);
+
+			snd_dev->cport_active = false;
+		}
+
 		return;
+	} else if (!snd_dev->cport_active) {
+		ret = gb_i2s_mgmt_activate_cport(snd_dev->mgmt_connection,
+						 CONFIG_I2S_REMOTE_DATA_CPORT);
+		if (ret)
+			pr_err("activate_cport failed: %d\n", ret);
+
+		snd_dev->cport_active = true;
+	}
 
 	address = runtime->dma_area + snd_dev->hwptr_done;
 
@@ -88,6 +106,7 @@ static enum hrtimer_restart gb_pcm_timer_function(struct hrtimer *hrtimer)
 void gb_pcm_hrtimer_start(struct gb_snd *snd_dev)
 {
 	atomic_set(&snd_dev->running, 1);
+	queue_work(snd_dev->workqueue, &snd_dev->work); /* Activates CPort */
 	hrtimer_start(&snd_dev->timer, ns_to_ktime(CONFIG_PERIOD_NS),
 						HRTIMER_MODE_REL);
 }
@@ -96,6 +115,7 @@ void gb_pcm_hrtimer_stop(struct gb_snd *snd_dev)
 {
 	atomic_set(&snd_dev->running, 0);
 	hrtimer_cancel(&snd_dev->timer);
+	queue_work(snd_dev->workqueue, &snd_dev->work); /* Deactivates CPort */
 }
 
 static int gb_pcm_hrtimer_init(struct gb_snd *snd_dev)
diff --git a/drivers/staging/greybus/audio.c b/drivers/staging/greybus/audio.c
index 1cc7c04d562b18082f46878ceb0162135d11a2c9..1057e468d5d4f3240745177ba6bf04b15576246f 100644
--- a/drivers/staging/greybus/audio.c
+++ b/drivers/staging/greybus/audio.c
@@ -292,13 +292,11 @@ static int gb_i2s_mgmt_connection_init(struct gb_connection *connection)
 
 	if (!snd_dev->send_data_req_buf) {
 		ret = -ENOMEM;
-		goto err_deactivate_cport;
+		goto err_free_snd_dev;
 	}
 
 	return 0;
 
-err_deactivate_cport:
-	gb_i2s_mgmt_deactivate_cport(connection, CONFIG_I2S_REMOTE_DATA_CPORT);
 err_free_snd_dev:
 	gb_free_snd(snd_dev);
 	return ret;
@@ -307,12 +305,6 @@ static int gb_i2s_mgmt_connection_init(struct gb_connection *connection)
 static void gb_i2s_mgmt_connection_exit(struct gb_connection *connection)
 {
 	struct gb_snd *snd_dev = (struct gb_snd *)connection->private;
-	int ret;
-
-	ret = gb_i2s_mgmt_deactivate_cport(connection,
-					   CONFIG_I2S_REMOTE_DATA_CPORT);
-	if (ret)
-		pr_err("deactivate_cport failed: %d\n", ret);
 
 	kfree(snd_dev->send_data_req_buf);
 	snd_dev->send_data_req_buf = NULL;
diff --git a/drivers/staging/greybus/audio.h b/drivers/staging/greybus/audio.h
index 020a8fc1d26726edd4d341cc3caf73b342ae0c53..50a9ebb6612ee9035b28eeb5c329dc2fec38549d 100644
--- a/drivers/staging/greybus/audio.h
+++ b/drivers/staging/greybus/audio.h
@@ -53,6 +53,7 @@ struct gb_snd {
 	struct snd_pcm_substream	*substream;
 	struct hrtimer			timer;
 	atomic_t			running;
+	bool				cport_active;
 	struct workqueue_struct		*workqueue;
 	struct work_struct		work;
 	int				hwptr_done;