diff --git a/sound/soc/fsl/fsl_rpmsg_i2s.c b/sound/soc/fsl/fsl_rpmsg_i2s.c
index 192802ae339be49207b9aaf8bb01bb11c4e3c24d..c6836736662b73bb1da7ed2f6e9e66bdc4a9cfbe 100644
--- a/sound/soc/fsl/fsl_rpmsg_i2s.c
+++ b/sound/soc/fsl/fsl_rpmsg_i2s.c
@@ -149,6 +149,9 @@ static void rpmsg_i2s_work(struct work_struct *work)
 	i2s_info = work_of_rpmsg->i2s_info;
 
 	i2s_send_message(&work_of_rpmsg->msg, i2s_info);
+
+	i2s_info->work_read_index++;
+	i2s_info->work_read_index %= WORK_MAX_NUM;
 }
 
 static int fsl_rpmsg_i2s_probe(struct platform_device *pdev)
@@ -179,6 +182,7 @@ static int fsl_rpmsg_i2s_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	i2s_info->work_write_index = 1;
 	i2s_info->send_message = i2s_send_message;
 
 	for (i = 0; i < WORK_MAX_NUM; i++) {
diff --git a/sound/soc/fsl/fsl_rpmsg_i2s.h b/sound/soc/fsl/fsl_rpmsg_i2s.h
index 36d6c5f51360039bf58166cbd6a7d1d2e80ab12e..14922f1a7690807f458cd8bf3020ab22a1088a77 100644
--- a/sound/soc/fsl/fsl_rpmsg_i2s.h
+++ b/sound/soc/fsl/fsl_rpmsg_i2s.h
@@ -309,7 +309,7 @@
 
 #define         I2S_TYPE_A_NUM          0x18
 
-#define         WORK_MAX_NUM		0x18
+#define         WORK_MAX_NUM		0x30
 
 #define		I2S_TX_PERIOD_DONE	0x0
 #define		I2S_RX_PERIOD_DONE	0x1
@@ -397,7 +397,9 @@ struct i2s_info {
 
 	struct workqueue_struct  *rpmsg_wq;
 	struct work_of_rpmsg	 work_list[WORK_MAX_NUM];
-	int                      work_index;
+	int                      work_write_index;
+	int                      work_read_index;
+	int                      msg_drop_count[2];
 	int                      num_period[2];
 	void                     *callback_param[2];
 	int (*send_message)(struct i2s_rpmsg *msg, struct i2s_info *info);
diff --git a/sound/soc/fsl/imx-pcm-rpmsg.c b/sound/soc/fsl/imx-pcm-rpmsg.c
index c61dc98dd335386d933c1dd85cea5141b0e52b56..1cbdf4215c11e69700babcb43ab7aa5cb5fe5c20 100644
--- a/sound/soc/fsl/imx-pcm-rpmsg.c
+++ b/sound/soc/fsl/imx-pcm-rpmsg.c
@@ -127,7 +127,7 @@ static void imx_rpmsg_timer_callback(unsigned long data)
 	struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
 	struct i2s_info      *i2s_info =  &rpmsg_i2s->i2s_info;
 	struct i2s_rpmsg     *rpmsg;
-	u8 index = i2s_info->work_index;
+	int index = i2s_info->work_write_index;
 	int time_msec;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -140,11 +140,14 @@ static void imx_rpmsg_timer_callback(unsigned long data)
 	else
 		rpmsg->send_msg.header.cmd = I2S_RX_POINTER;
 
-	memcpy(&i2s_info->work_list[index].msg, rpmsg,
+	if (i2s_info->work_write_index != i2s_info->work_read_index) {
+		memcpy(&i2s_info->work_list[index].msg, rpmsg,
 					sizeof(struct i2s_rpmsg_s));
-	queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
-	i2s_info->work_index++;
-	i2s_info->work_index %= WORK_MAX_NUM;
+		queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+		i2s_info->work_write_index++;
+		i2s_info->work_write_index %= WORK_MAX_NUM;
+	} else
+		i2s_info->msg_drop_count[substream->stream]++;
 
 	if (rpmsg_i2s->force_lpa) {
 		time_msec = (int)(runtime->period_size*1000/runtime->rate);
@@ -208,6 +211,7 @@ static int imx_rpmsg_pcm_open(struct snd_pcm_substream *substream)
 	if (ret < 0)
 		return ret;
 
+	i2s_info->msg_drop_count[substream->stream] = 0;
 
 	/*create thread*/
 	setup_timer(&i2s_info->stream_timer[substream->stream],
@@ -243,6 +247,10 @@ static int imx_rpmsg_pcm_close(struct snd_pcm_substream *substream)
 
 	kfree(prtd);
 
+	if (i2s_info->msg_drop_count[substream->stream])
+		dev_warn(rtd->dev, "Msg is dropped!, number is %d\n",
+			i2s_info->msg_drop_count[substream->stream]);
+
 	return ret;
 }
 
@@ -324,7 +332,7 @@ static int imx_rpmsg_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
 	struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
 	struct i2s_info      *i2s_info =  &rpmsg_i2s->i2s_info;
 	struct i2s_rpmsg   *rpmsg;
-	u8 index = i2s_info->work_index;
+	int index = i2s_info->work_write_index;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		rpmsg = &i2s_info->rpmsg[I2S_TX_BUFFER];
@@ -346,18 +354,21 @@ static int imx_rpmsg_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
 			rpmsg->send_msg.param.buffer_size /
 				rpmsg->send_msg.param.period_size;
 
-	memcpy(&i2s_info->work_list[index].msg, rpmsg,
+	if (i2s_info->work_write_index != i2s_info->work_read_index) {
+		memcpy(&i2s_info->work_list[index].msg, rpmsg,
 					sizeof(struct i2s_rpmsg_s));
-	queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
-	i2s_info->work_index++;
-	i2s_info->work_index %= WORK_MAX_NUM;
+		queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+		i2s_info->work_write_index++;
+		i2s_info->work_write_index %= WORK_MAX_NUM;
+	} else
+		return -EPIPE;
 
 	i2s_info->callback[substream->stream] = imx_rpmsg_pcm_dma_complete;
 	i2s_info->callback_param[substream->stream] = substream;
 	return 0;
 }
 
-static void imx_rpmsg_async_issue_pending(struct snd_pcm_substream *substream)
+static int imx_rpmsg_async_issue_pending(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -365,7 +376,7 @@ static void imx_rpmsg_async_issue_pending(struct snd_pcm_substream *substream)
 	struct fsl_rpmsg_i2s *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
 	struct i2s_info      *i2s_info =  &rpmsg_i2s->i2s_info;
 	struct i2s_rpmsg     *rpmsg;
-	u8 index = i2s_info->work_index;
+	int index = i2s_info->work_write_index;
 	int time_msec;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -378,17 +389,22 @@ static void imx_rpmsg_async_issue_pending(struct snd_pcm_substream *substream)
 	else
 		rpmsg->send_msg.header.cmd = I2S_RX_START;
 
-	memcpy(&i2s_info->work_list[index].msg, rpmsg,
-					sizeof(struct i2s_rpmsg_s));
-	queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
-	i2s_info->work_index++;
-	i2s_info->work_index %= WORK_MAX_NUM;
+	if (i2s_info->work_write_index != i2s_info->work_read_index) {
+		memcpy(&i2s_info->work_list[index].msg, rpmsg,
+						sizeof(struct i2s_rpmsg_s));
+		queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+		i2s_info->work_write_index++;
+		i2s_info->work_write_index %= WORK_MAX_NUM;
+	} else
+		return -EPIPE;
 
 	if (rpmsg_i2s->force_lpa) {
 		time_msec = (int)(runtime->period_size*1000/runtime->rate);
 		mod_timer(&i2s_info->stream_timer[substream->stream],
 			    jiffies + msecs_to_jiffies(time_msec));
 	}
+
+	return 0;
 }
 
 static int imx_rpmsg_restart(struct snd_pcm_substream *substream)
@@ -398,7 +414,7 @@ static int imx_rpmsg_restart(struct snd_pcm_substream *substream)
 	struct fsl_rpmsg_i2s       *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
 	struct i2s_info            *i2s_info =  &rpmsg_i2s->i2s_info;
 	struct i2s_rpmsg     *rpmsg;
-	u8 index = i2s_info->work_index;
+	int index = i2s_info->work_write_index;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		rpmsg = &i2s_info->rpmsg[I2S_TX_RESTART];
@@ -410,11 +426,14 @@ static int imx_rpmsg_restart(struct snd_pcm_substream *substream)
 	else
 		rpmsg->send_msg.header.cmd = I2S_RX_RESTART;
 
-	memcpy(&i2s_info->work_list[index].msg, rpmsg,
+	if (i2s_info->work_write_index != i2s_info->work_read_index) {
+		memcpy(&i2s_info->work_list[index].msg, rpmsg,
 					sizeof(struct i2s_rpmsg_s));
-	queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
-	i2s_info->work_index++;
-	i2s_info->work_index %= WORK_MAX_NUM;
+		queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+		i2s_info->work_write_index++;
+		i2s_info->work_write_index %= WORK_MAX_NUM;
+	} else
+		return -EPIPE;
 
 	return 0;
 }
@@ -426,7 +445,7 @@ static int imx_rpmsg_pause(struct snd_pcm_substream *substream)
 	struct fsl_rpmsg_i2s       *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
 	struct i2s_info            *i2s_info =  &rpmsg_i2s->i2s_info;
 	struct i2s_rpmsg     *rpmsg;
-	u8 index = i2s_info->work_index;
+	int index = i2s_info->work_write_index;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		rpmsg = &i2s_info->rpmsg[I2S_TX_PAUSE];
@@ -438,11 +457,15 @@ static int imx_rpmsg_pause(struct snd_pcm_substream *substream)
 	else
 		rpmsg->send_msg.header.cmd = I2S_RX_PAUSE;
 
-	memcpy(&i2s_info->work_list[index].msg, rpmsg,
-					sizeof(struct i2s_rpmsg_s));
-	queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
-	i2s_info->work_index++;
-	i2s_info->work_index %= WORK_MAX_NUM;
+	if (i2s_info->work_write_index != i2s_info->work_read_index) {
+		memcpy(&i2s_info->work_list[index].msg, rpmsg,
+						sizeof(struct i2s_rpmsg_s));
+		queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+		i2s_info->work_write_index++;
+		i2s_info->work_write_index %= WORK_MAX_NUM;
+	} else
+		return -EPIPE;
+
 	return 0;
 }
 
@@ -453,7 +476,7 @@ static int imx_rpmsg_terminate_all(struct snd_pcm_substream *substream)
 	struct fsl_rpmsg_i2s       *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
 	struct i2s_info            *i2s_info =  &rpmsg_i2s->i2s_info;
 	struct i2s_rpmsg     *rpmsg;
-	u8 index = i2s_info->work_index;
+	int index = i2s_info->work_write_index;
 	int cmd;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -466,12 +489,6 @@ static int imx_rpmsg_terminate_all(struct snd_pcm_substream *substream)
 	else
 		rpmsg->send_msg.header.cmd = I2S_RX_TERMINATE;
 
-	memcpy(&i2s_info->work_list[index].msg, rpmsg,
-					sizeof(struct i2s_rpmsg_s));
-	queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
-	i2s_info->work_index++;
-	i2s_info->work_index %= WORK_MAX_NUM;
-
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		cmd = I2S_TX_PERIOD_DONE + I2S_TYPE_A_NUM;
 		i2s_info->rpmsg[cmd].send_msg.param.buffer_tail = 0;
@@ -485,6 +502,16 @@ static int imx_rpmsg_terminate_all(struct snd_pcm_substream *substream)
 	}
 
 	del_timer(&i2s_info->stream_timer[substream->stream]);
+
+	if (i2s_info->work_write_index != i2s_info->work_read_index) {
+		memcpy(&i2s_info->work_list[index].msg, rpmsg,
+					sizeof(struct i2s_rpmsg_s));
+		queue_work(i2s_info->rpmsg_wq, &i2s_info->work_list[index].work);
+		i2s_info->work_write_index++;
+		i2s_info->work_write_index %= WORK_MAX_NUM;
+	} else
+		return -EPIPE;
+
 	return 0;
 }
 
@@ -495,14 +522,14 @@ int imx_rpmsg_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 	struct snd_soc_dai     *cpu_dai = rtd->cpu_dai;
 	struct fsl_rpmsg_i2s   *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
 	struct i2s_info        *i2s_info =  &rpmsg_i2s->i2s_info;
-	int ret;
+	int ret = 0;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 		ret = imx_rpmsg_pcm_prepare_and_submit(substream);
 		if (ret)
 			return ret;
-		imx_rpmsg_async_issue_pending(substream);
+		ret = imx_rpmsg_async_issue_pending(substream);
 		break;
 	case SNDRV_PCM_TRIGGER_RESUME:
 		if (rpmsg_i2s->force_lpa) {
@@ -514,27 +541,30 @@ int imx_rpmsg_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 			break;
 		}
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		imx_rpmsg_restart(substream);
+		ret = imx_rpmsg_restart(substream);
 		break;
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 		if (!rpmsg_i2s->force_lpa) {
 			if (runtime->info & SNDRV_PCM_INFO_PAUSE)
-				imx_rpmsg_pause(substream);
+				ret = imx_rpmsg_pause(substream);
 			else
-				imx_rpmsg_terminate_all(substream);
+				ret = imx_rpmsg_terminate_all(substream);
 		} else
 			del_timer(&i2s_info->stream_timer[substream->stream]);
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		imx_rpmsg_pause(substream);
+		ret = imx_rpmsg_pause(substream);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
-		imx_rpmsg_terminate_all(substream);
+		ret = imx_rpmsg_terminate_all(substream);
 		break;
 	default:
 		return -EINVAL;
 	}
 
+	if (ret)
+		return ret;
+
 	return 0;
 }
 
@@ -547,7 +577,7 @@ int imx_rpmsg_pcm_ack(struct snd_pcm_substream *substream)
 	struct fsl_rpmsg_i2s       *rpmsg_i2s = dev_get_drvdata(cpu_dai->dev);
 	struct i2s_info            *i2s_info =  &rpmsg_i2s->i2s_info;
 	struct i2s_rpmsg           *rpmsg;
-	u8 index = i2s_info->work_index;
+	int index = i2s_info->work_write_index;
 	int buffer_tail = 0;
 
 	if (!rpmsg_i2s->force_lpa)
@@ -571,12 +601,15 @@ int imx_rpmsg_pcm_ack(struct snd_pcm_substream *substream)
 
 	if (buffer_tail != rpmsg->send_msg.param.buffer_tail) {
 		rpmsg->send_msg.param.buffer_tail = buffer_tail;
-		memcpy(&i2s_info->work_list[index].msg, rpmsg,
+		if (i2s_info->work_write_index != i2s_info->work_read_index) {
+			memcpy(&i2s_info->work_list[index].msg, rpmsg,
 					sizeof(struct i2s_rpmsg_s));
-		queue_work(i2s_info->rpmsg_wq,
+			queue_work(i2s_info->rpmsg_wq,
 					&i2s_info->work_list[index].work);
-		i2s_info->work_index++;
-		i2s_info->work_index %= WORK_MAX_NUM;
+			i2s_info->work_write_index++;
+			i2s_info->work_write_index %= WORK_MAX_NUM;
+		} else
+			i2s_info->msg_drop_count[substream->stream]++;
 	}
 
 	return 0;