// SPDX-License-Identifier: GPL-2.0+
// Copyright 2017-2021 NXP

#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/rpmsg.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/dmaengine_pcm.h>
#include <sound/soc.h>

#include "imx-pcm.h"
#include "fsl_rpmsg.h"
#include "imx-pcm-rpmsg.h"

static struct snd_pcm_hardware imx_rpmsg_pcm_hardware = {
	.info = SNDRV_PCM_INFO_INTERLEAVED |
		SNDRV_PCM_INFO_BLOCK_TRANSFER |
		SNDRV_PCM_INFO_BATCH |
		SNDRV_PCM_INFO_MMAP |
		SNDRV_PCM_INFO_MMAP_VALID |
		SNDRV_PCM_INFO_NO_PERIOD_WAKEUP |
		SNDRV_PCM_INFO_PAUSE |
		SNDRV_PCM_INFO_RESUME,
	.buffer_bytes_max = IMX_DEFAULT_DMABUF_SIZE,
	.period_bytes_min = 512,
	.period_bytes_max = 65536,
	.periods_min = 2,
	.periods_max = 6000,
	.fifo_size = 0,
};

static int imx_rpmsg_pcm_send_message(struct rpmsg_msg *msg,
				      struct rpmsg_info *info)
{
	struct rpmsg_device *rpdev = info->rpdev;
	int ret = 0;

	mutex_lock(&info->msg_lock);
	if (!rpdev) {
		dev_err(info->dev, "rpmsg channel not ready\n");
		mutex_unlock(&info->msg_lock);
		return -EINVAL;
	}

	dev_dbg(&rpdev->dev, "send cmd %d\n", msg->s_msg.header.cmd);

	if (!(msg->s_msg.header.type == MSG_TYPE_C))
		reinit_completion(&info->cmd_complete);

	ret = rpmsg_send(rpdev->ept, (void *)&msg->s_msg,
			 sizeof(struct rpmsg_s_msg));
	if (ret) {
		dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
		mutex_unlock(&info->msg_lock);
		return ret;
	}

	/* No receive msg for TYPE_C command */
	if (msg->s_msg.header.type == MSG_TYPE_C) {
		mutex_unlock(&info->msg_lock);
		return 0;
	}

	/* wait response from rpmsg */
	ret = wait_for_completion_timeout(&info->cmd_complete,
					  msecs_to_jiffies(RPMSG_TIMEOUT));
	if (!ret) {
		dev_err(&rpdev->dev, "rpmsg_send cmd %d timeout!\n",
			msg->s_msg.header.cmd);
		mutex_unlock(&info->msg_lock);
		return -ETIMEDOUT;
	}

	memcpy(&msg->r_msg, &info->r_msg, sizeof(struct rpmsg_r_msg));
	memcpy(&info->msg[msg->r_msg.header.cmd].r_msg,
	       &msg->r_msg, sizeof(struct rpmsg_r_msg));

	/*
	 * Reset the buffer pointer to be zero, actully we have
	 * set the buffer pointer to be zero in imx_rpmsg_terminate_all
	 * But if there is timer task queued in queue, after it is
	 * executed the buffer pointer will be changed, so need to
	 * reset it again with TERMINATE command.
	 */
	switch (msg->s_msg.header.cmd) {
	case TX_TERMINATE:
		info->msg[TX_POINTER].r_msg.param.buffer_offset = 0;
		break;
	case RX_TERMINATE:
		info->msg[RX_POINTER].r_msg.param.buffer_offset = 0;
		break;
	default:
		break;
	}

	dev_dbg(&rpdev->dev, "cmd:%d, resp %d\n", msg->s_msg.header.cmd,
		info->r_msg.param.resp);

	mutex_unlock(&info->msg_lock);

	return 0;
}

static int imx_rpmsg_insert_workqueue(struct snd_pcm_substream *substream,
				      struct rpmsg_msg *msg,
				      struct rpmsg_info *info)
{
	unsigned long flags;
	int ret = 0;

	/*
	 * Queue the work to workqueue.
	 * If the queue is full, drop the message.
	 */
	spin_lock_irqsave(&info->wq_lock, flags);
	if (info->work_write_index != info->work_read_index) {
		int index = info->work_write_index;

		memcpy(&info->work_list[index].msg, msg,
		       sizeof(struct rpmsg_s_msg));

		queue_work(info->rpmsg_wq, &info->work_list[index].work);
		info->work_write_index++;
		info->work_write_index %= WORK_MAX_NUM;
	} else {
		info->msg_drop_count[substream->stream]++;
		ret = -EPIPE;
	}
	spin_unlock_irqrestore(&info->wq_lock, flags);

	return ret;
}

static int imx_rpmsg_pcm_hw_params(struct snd_soc_component *component,
				   struct snd_pcm_substream *substream,
				   struct snd_pcm_hw_params *params)
{
	struct rpmsg_info *info = dev_get_drvdata(component->dev);
	struct rpmsg_msg *msg;
	int ret = 0;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		msg = &info->msg[TX_HW_PARAM];
		msg->s_msg.header.cmd = TX_HW_PARAM;
	} else {
		msg = &info->msg[RX_HW_PARAM];
		msg->s_msg.header.cmd = RX_HW_PARAM;
	}

	msg->s_msg.param.rate = params_rate(params);

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		msg->s_msg.param.format   = RPMSG_S16_LE;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		msg->s_msg.param.format   = RPMSG_S24_LE;
		break;
	case SNDRV_PCM_FORMAT_DSD_U16_LE:
		msg->s_msg.param.format   = RPMSG_DSD_U16_LE;
		break;
	case SNDRV_PCM_FORMAT_DSD_U32_LE:
		msg->s_msg.param.format   = RPMSG_DSD_U32_LE;
		break;
	default:
		msg->s_msg.param.format   = RPMSG_S32_LE;
		break;
	}

	switch (params_channels(params)) {
	case 1:
		msg->s_msg.param.channels = RPMSG_CH_LEFT;
		break;
	case 2:
		msg->s_msg.param.channels = RPMSG_CH_STEREO;
		break;
	default:
		ret = -EINVAL;
		break;
	}

	info->send_message(msg, info);

	return ret;
}

static snd_pcm_uframes_t imx_rpmsg_pcm_pointer(struct snd_soc_component *component,
					       struct snd_pcm_substream *substream)
{
	struct rpmsg_info *info = dev_get_drvdata(component->dev);
	struct rpmsg_msg *msg;
	unsigned int pos = 0;
	int buffer_tail = 0;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		msg = &info->msg[TX_PERIOD_DONE + MSG_TYPE_A_NUM];
	else
		msg = &info->msg[RX_PERIOD_DONE + MSG_TYPE_A_NUM];

	buffer_tail = msg->r_msg.param.buffer_tail;
	pos = buffer_tail * snd_pcm_lib_period_bytes(substream);

	return bytes_to_frames(substream->runtime, pos);
}

static void imx_rpmsg_timer_callback(struct timer_list *t)
{
	struct stream_timer  *stream_timer =
			from_timer(stream_timer, t, timer);
	struct snd_pcm_substream *substream = stream_timer->substream;
	struct rpmsg_info *info = stream_timer->info;
	struct rpmsg_msg *msg;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		msg = &info->msg[TX_PERIOD_DONE + MSG_TYPE_A_NUM];
		msg->s_msg.header.cmd = TX_PERIOD_DONE;
	} else {
		msg = &info->msg[RX_PERIOD_DONE + MSG_TYPE_A_NUM];
		msg->s_msg.header.cmd = RX_PERIOD_DONE;
	}

	imx_rpmsg_insert_workqueue(substream, msg, info);
}

static int imx_rpmsg_pcm_open(struct snd_soc_component *component,
			      struct snd_pcm_substream *substream)
{
	struct rpmsg_info *info = dev_get_drvdata(component->dev);
	struct rpmsg_msg *msg;
	int ret = 0;
	int cmd;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		msg = &info->msg[TX_OPEN];
		msg->s_msg.header.cmd = TX_OPEN;

		/* reinitialize buffer counter*/
		cmd = TX_PERIOD_DONE + MSG_TYPE_A_NUM;
		info->msg[cmd].s_msg.param.buffer_tail = 0;
		info->msg[cmd].r_msg.param.buffer_tail = 0;
		info->msg[TX_POINTER].r_msg.param.buffer_offset = 0;

	} else {
		msg = &info->msg[RX_OPEN];
		msg->s_msg.header.cmd = RX_OPEN;

		/* reinitialize buffer counter*/
		cmd = RX_PERIOD_DONE + MSG_TYPE_A_NUM;
		info->msg[cmd].s_msg.param.buffer_tail = 0;
		info->msg[cmd].r_msg.param.buffer_tail = 0;
		info->msg[RX_POINTER].r_msg.param.buffer_offset = 0;
	}

	info->send_message(msg, info);

	imx_rpmsg_pcm_hardware.period_bytes_max =
			imx_rpmsg_pcm_hardware.buffer_bytes_max / 2;

	snd_soc_set_runtime_hwparams(substream, &imx_rpmsg_pcm_hardware);

	ret = snd_pcm_hw_constraint_integer(substream->runtime,
					    SNDRV_PCM_HW_PARAM_PERIODS);
	if (ret < 0)
		return ret;

	info->msg_drop_count[substream->stream] = 0;

	/* Create timer*/
	info->stream_timer[substream->stream].info = info;
	info->stream_timer[substream->stream].substream = substream;
	timer_setup(&info->stream_timer[substream->stream].timer,
		    imx_rpmsg_timer_callback, 0);
	return ret;
}

static int imx_rpmsg_pcm_close(struct snd_soc_component *component,
			       struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
	struct rpmsg_info *info = dev_get_drvdata(component->dev);
	struct rpmsg_msg *msg;
	int ret = 0;

	/* Flush work in workqueue to make TX_CLOSE is the last message */
	flush_workqueue(info->rpmsg_wq);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		msg = &info->msg[TX_CLOSE];
		msg->s_msg.header.cmd = TX_CLOSE;
	} else {
		msg = &info->msg[RX_CLOSE];
		msg->s_msg.header.cmd = RX_CLOSE;
	}

	info->send_message(msg, info);

	del_timer(&info->stream_timer[substream->stream].timer);

	rtd->dai_link->ignore_suspend = 0;

	if (info->msg_drop_count[substream->stream])
		dev_warn(rtd->dev, "Msg is dropped!, number is %d\n",
			 info->msg_drop_count[substream->stream]);

	return ret;
}

static int imx_rpmsg_pcm_prepare(struct snd_soc_component *component,
				 struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
	struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev);

	/*
	 * NON-MMAP mode, NONBLOCK, Version 2, enable lpa in dts
	 * four conditions to determine the lpa is enabled.
	 */
	if ((runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
	     runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) &&
	     rpmsg->enable_lpa) {
		/*
		 * Ignore suspend operation in low power mode
		 * M core will continue playback music on A core suspend.
		 */
		rtd->dai_link->ignore_suspend = 1;
		rpmsg->force_lpa = 1;
	} else {
		rpmsg->force_lpa = 0;
	}

	return 0;
}

static void imx_rpmsg_pcm_dma_complete(void *arg)
{
	struct snd_pcm_substream *substream = arg;

	snd_pcm_period_elapsed(substream);
}

static int imx_rpmsg_prepare_and_submit(struct snd_soc_component *component,
					struct snd_pcm_substream *substream)
{
	struct rpmsg_info *info = dev_get_drvdata(component->dev);
	struct rpmsg_msg *msg;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		msg = &info->msg[TX_BUFFER];
		msg->s_msg.header.cmd = TX_BUFFER;
	} else {
		msg = &info->msg[RX_BUFFER];
		msg->s_msg.header.cmd = RX_BUFFER;
	}

	/* Send buffer address and buffer size */
	msg->s_msg.param.buffer_addr = substream->runtime->dma_addr;
	msg->s_msg.param.buffer_size = snd_pcm_lib_buffer_bytes(substream);
	msg->s_msg.param.period_size = snd_pcm_lib_period_bytes(substream);
	msg->s_msg.param.buffer_tail = 0;

	info->num_period[substream->stream] = msg->s_msg.param.buffer_size /
					      msg->s_msg.param.period_size;

	info->callback[substream->stream] = imx_rpmsg_pcm_dma_complete;
	info->callback_param[substream->stream] = substream;

	return imx_rpmsg_insert_workqueue(substream, msg, info);
}

static int imx_rpmsg_async_issue_pending(struct snd_soc_component *component,
					 struct snd_pcm_substream *substream)
{
	struct rpmsg_info *info = dev_get_drvdata(component->dev);
	struct rpmsg_msg *msg;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		msg = &info->msg[TX_START];
		msg->s_msg.header.cmd = TX_START;
	} else {
		msg = &info->msg[RX_START];
		msg->s_msg.header.cmd = RX_START;
	}

	return imx_rpmsg_insert_workqueue(substream, msg, info);
}

static int imx_rpmsg_restart(struct snd_soc_component *component,
			     struct snd_pcm_substream *substream)
{
	struct rpmsg_info *info = dev_get_drvdata(component->dev);
	struct rpmsg_msg *msg;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		msg = &info->msg[TX_RESTART];
		msg->s_msg.header.cmd = TX_RESTART;
	} else {
		msg = &info->msg[RX_RESTART];
		msg->s_msg.header.cmd = RX_RESTART;
	}

	return imx_rpmsg_insert_workqueue(substream, msg, info);
}

static int imx_rpmsg_pause(struct snd_soc_component *component,
			   struct snd_pcm_substream *substream)
{
	struct rpmsg_info *info = dev_get_drvdata(component->dev);
	struct rpmsg_msg *msg;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		msg = &info->msg[TX_PAUSE];
		msg->s_msg.header.cmd = TX_PAUSE;
	} else {
		msg = &info->msg[RX_PAUSE];
		msg->s_msg.header.cmd = RX_PAUSE;
	}

	return imx_rpmsg_insert_workqueue(substream, msg, info);
}

static int imx_rpmsg_terminate_all(struct snd_soc_component *component,
				   struct snd_pcm_substream *substream)
{
	struct rpmsg_info *info = dev_get_drvdata(component->dev);
	struct rpmsg_msg *msg;
	int cmd;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		msg = &info->msg[TX_TERMINATE];
		msg->s_msg.header.cmd = TX_TERMINATE;
		/* Clear buffer count*/
		cmd = TX_PERIOD_DONE + MSG_TYPE_A_NUM;
		info->msg[cmd].s_msg.param.buffer_tail = 0;
		info->msg[cmd].r_msg.param.buffer_tail = 0;
		info->msg[TX_POINTER].r_msg.param.buffer_offset = 0;
	} else {
		msg = &info->msg[RX_TERMINATE];
		msg->s_msg.header.cmd = RX_TERMINATE;
		/* Clear buffer count*/
		cmd = RX_PERIOD_DONE + MSG_TYPE_A_NUM;
		info->msg[cmd].s_msg.param.buffer_tail = 0;
		info->msg[cmd].r_msg.param.buffer_tail = 0;
		info->msg[RX_POINTER].r_msg.param.buffer_offset = 0;
	}

	del_timer(&info->stream_timer[substream->stream].timer);

	return imx_rpmsg_insert_workqueue(substream, msg, info);
}

static int imx_rpmsg_pcm_trigger(struct snd_soc_component *component,
				 struct snd_pcm_substream *substream, int cmd)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
	struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev);
	int ret = 0;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		ret = imx_rpmsg_prepare_and_submit(component, substream);
		if (ret)
			return ret;
		ret = imx_rpmsg_async_issue_pending(component, substream);
		break;
	case SNDRV_PCM_TRIGGER_RESUME:
		if (rpmsg->force_lpa)
			break;
		fallthrough;
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		ret = imx_rpmsg_restart(component, substream);
		break;
	case SNDRV_PCM_TRIGGER_SUSPEND:
		if (!rpmsg->force_lpa) {
			if (runtime->info & SNDRV_PCM_INFO_PAUSE)
				ret = imx_rpmsg_pause(component, substream);
			else
				ret = imx_rpmsg_terminate_all(component, substream);
		}
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		ret = imx_rpmsg_pause(component, substream);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		ret = imx_rpmsg_terminate_all(component, substream);
		break;
	default:
		return -EINVAL;
	}

	if (ret)
		return ret;

	return 0;
}

/*
 * imx_rpmsg_pcm_ack
 *
 * Send the period index to M core through rpmsg, but not send
 * all the period index to M core, reduce some unnessesary msg
 * to reduce the pressure of rpmsg bandwidth.
 */
static int imx_rpmsg_pcm_ack(struct snd_soc_component *component,
			     struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
	struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev);
	struct rpmsg_info *info = dev_get_drvdata(component->dev);
	snd_pcm_uframes_t period_size = runtime->period_size;
	snd_pcm_sframes_t avail;
	struct timer_list *timer;
	struct rpmsg_msg *msg;
	unsigned long flags;
	int buffer_tail = 0;
	int written_num;

	if (!rpmsg->force_lpa)
		return 0;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		msg = &info->msg[TX_PERIOD_DONE + MSG_TYPE_A_NUM];
		msg->s_msg.header.cmd = TX_PERIOD_DONE;
	} else {
		msg = &info->msg[RX_PERIOD_DONE + MSG_TYPE_A_NUM];
		msg->s_msg.header.cmd = RX_PERIOD_DONE;
	}

	msg->s_msg.header.type = MSG_TYPE_C;

	buffer_tail = (frames_to_bytes(runtime, runtime->control->appl_ptr) %
		       snd_pcm_lib_buffer_bytes(substream));
	buffer_tail = buffer_tail / snd_pcm_lib_period_bytes(substream);

	/* There is update for period index */
	if (buffer_tail != msg->s_msg.param.buffer_tail) {
		written_num = buffer_tail - msg->s_msg.param.buffer_tail;
		if (written_num < 0)
			written_num += runtime->periods;

		msg->s_msg.param.buffer_tail = buffer_tail;

		/* The notification message is updated to latest */
		spin_lock_irqsave(&info->lock[substream->stream], flags);
		memcpy(&info->notify[substream->stream], msg,
		       sizeof(struct rpmsg_s_msg));
		info->notify_updated[substream->stream] = true;
		spin_unlock_irqrestore(&info->lock[substream->stream], flags);

		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
			avail = snd_pcm_playback_hw_avail(runtime);
		else
			avail = snd_pcm_capture_hw_avail(runtime);

		timer = &info->stream_timer[substream->stream].timer;
		/*
		 * If the data in the buffer is less than one period before
		 * this fill, which means the data may not enough on M
		 * core side, we need to send message immediately to let
		 * M core know the pointer is updated.
		 * if there is more than one period data in the buffer before
		 * this fill, which means the data is enough on M core side,
		 * we can delay one period (using timer) to send the message
		 * for reduce the message number in workqueue, because the
		 * pointer may be updated by ack function later, we can
		 * send latest pointer to M core side.
		 */
		if ((avail - written_num * period_size) <= period_size) {
			imx_rpmsg_insert_workqueue(substream, msg, info);
		} else if (rpmsg->force_lpa && !timer_pending(timer)) {
			int time_msec;

			time_msec = (int)(runtime->period_size * 1000 / runtime->rate);
			mod_timer(timer, jiffies + msecs_to_jiffies(time_msec));
		}
	}

	return 0;
}

static int imx_rpmsg_pcm_new(struct snd_soc_component *component,
			     struct snd_soc_pcm_runtime *rtd)
{
	struct snd_card *card = rtd->card->snd_card;
	struct snd_pcm *pcm = rtd->pcm;
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
	struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev);
	int ret;

	ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
	if (ret)
		return ret;

	imx_rpmsg_pcm_hardware.buffer_bytes_max = rpmsg->buffer_size;
	return snd_pcm_set_fixed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV_WC,
					    pcm->card->dev, rpmsg->buffer_size);
}

static const struct snd_soc_component_driver imx_rpmsg_soc_component = {
	.name		= IMX_PCM_DRV_NAME,
	.pcm_construct	= imx_rpmsg_pcm_new,
	.open		= imx_rpmsg_pcm_open,
	.close		= imx_rpmsg_pcm_close,
	.hw_params	= imx_rpmsg_pcm_hw_params,
	.trigger	= imx_rpmsg_pcm_trigger,
	.pointer	= imx_rpmsg_pcm_pointer,
	.ack		= imx_rpmsg_pcm_ack,
	.prepare	= imx_rpmsg_pcm_prepare,
};

static void imx_rpmsg_pcm_work(struct work_struct *work)
{
	struct work_of_rpmsg *work_of_rpmsg;
	bool is_notification = false;
	struct rpmsg_info *info;
	struct rpmsg_msg msg;
	unsigned long flags;

	work_of_rpmsg = container_of(work, struct work_of_rpmsg, work);
	info = work_of_rpmsg->info;

	/*
	 * Every work in the work queue, first we check if there
	 * is update for period is filled, because there may be not
	 * enough data in M core side, need to let M core know
	 * data is updated immediately.
	 */
	spin_lock_irqsave(&info->lock[TX], flags);
	if (info->notify_updated[TX]) {
		memcpy(&msg, &info->notify[TX], sizeof(struct rpmsg_s_msg));
		info->notify_updated[TX] = false;
		spin_unlock_irqrestore(&info->lock[TX], flags);
		info->send_message(&msg, info);
	} else {
		spin_unlock_irqrestore(&info->lock[TX], flags);
	}

	spin_lock_irqsave(&info->lock[RX], flags);
	if (info->notify_updated[RX]) {
		memcpy(&msg, &info->notify[RX], sizeof(struct rpmsg_s_msg));
		info->notify_updated[RX] = false;
		spin_unlock_irqrestore(&info->lock[RX], flags);
		info->send_message(&msg, info);
	} else {
		spin_unlock_irqrestore(&info->lock[RX], flags);
	}

	/* Skip the notification message for it has been processed above */
	if (work_of_rpmsg->msg.s_msg.header.type == MSG_TYPE_C &&
	    (work_of_rpmsg->msg.s_msg.header.cmd == TX_PERIOD_DONE ||
	     work_of_rpmsg->msg.s_msg.header.cmd == RX_PERIOD_DONE))
		is_notification = true;

	if (!is_notification)
		info->send_message(&work_of_rpmsg->msg, info);

	/* update read index */
	spin_lock_irqsave(&info->wq_lock, flags);
	info->work_read_index++;
	info->work_read_index %= WORK_MAX_NUM;
	spin_unlock_irqrestore(&info->wq_lock, flags);
}

static int imx_rpmsg_pcm_probe(struct platform_device *pdev)
{
	struct snd_soc_component *component;
	struct rpmsg_info *info;
	int ret, i;

	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	platform_set_drvdata(pdev, info);

	info->rpdev = container_of(pdev->dev.parent, struct rpmsg_device, dev);
	info->dev = &pdev->dev;
	/* Setup work queue */
	info->rpmsg_wq = alloc_ordered_workqueue("rpmsg_audio",
						 WQ_HIGHPRI |
						 WQ_UNBOUND |
						 WQ_FREEZABLE);
	if (!info->rpmsg_wq) {
		dev_err(&pdev->dev, "workqueue create failed\n");
		return -ENOMEM;
	}

	/* Write index initialize 1, make it differ with the read index */
	info->work_write_index = 1;
	info->send_message = imx_rpmsg_pcm_send_message;

	for (i = 0; i < WORK_MAX_NUM; i++) {
		INIT_WORK(&info->work_list[i].work, imx_rpmsg_pcm_work);
		info->work_list[i].info = info;
	}

	/* Initialize msg */
	for (i = 0; i < MSG_MAX_NUM; i++) {
		info->msg[i].s_msg.header.cate  = IMX_RPMSG_AUDIO;
		info->msg[i].s_msg.header.major = IMX_RMPSG_MAJOR;
		info->msg[i].s_msg.header.minor = IMX_RMPSG_MINOR;
		info->msg[i].s_msg.header.type  = MSG_TYPE_A;
		info->msg[i].s_msg.param.audioindex = 0;
	}

	init_completion(&info->cmd_complete);
	mutex_init(&info->msg_lock);
	spin_lock_init(&info->lock[TX]);
	spin_lock_init(&info->lock[RX]);
	spin_lock_init(&info->wq_lock);

	ret = devm_snd_soc_register_component(&pdev->dev,
					      &imx_rpmsg_soc_component,
					      NULL, 0);
	if (ret)
		goto fail;

	component = snd_soc_lookup_component(&pdev->dev, IMX_PCM_DRV_NAME);
	if (!component) {
		ret = -EINVAL;
		goto fail;
	}
#ifdef CONFIG_DEBUG_FS
	component->debugfs_prefix = "rpmsg";
#endif

	return 0;

fail:
	if (info->rpmsg_wq)
		destroy_workqueue(info->rpmsg_wq);

	return ret;
}

static int imx_rpmsg_pcm_remove(struct platform_device *pdev)
{
	struct rpmsg_info *info = platform_get_drvdata(pdev);

	if (info->rpmsg_wq)
		destroy_workqueue(info->rpmsg_wq);

	return 0;
}

#ifdef CONFIG_PM
static int imx_rpmsg_pcm_runtime_resume(struct device *dev)
{
	struct rpmsg_info *info = dev_get_drvdata(dev);

	cpu_latency_qos_add_request(&info->pm_qos_req, 0);

	return 0;
}

static int imx_rpmsg_pcm_runtime_suspend(struct device *dev)
{
	struct rpmsg_info *info = dev_get_drvdata(dev);

	cpu_latency_qos_remove_request(&info->pm_qos_req);

	return 0;
}
#endif

#ifdef CONFIG_PM_SLEEP
static int imx_rpmsg_pcm_suspend(struct device *dev)
{
	struct rpmsg_info *info = dev_get_drvdata(dev);
	struct rpmsg_msg *rpmsg_tx;
	struct rpmsg_msg *rpmsg_rx;

	rpmsg_tx = &info->msg[TX_SUSPEND];
	rpmsg_rx = &info->msg[RX_SUSPEND];

	rpmsg_tx->s_msg.header.cmd = TX_SUSPEND;
	info->send_message(rpmsg_tx, info);

	rpmsg_rx->s_msg.header.cmd = RX_SUSPEND;
	info->send_message(rpmsg_rx, info);

	return 0;
}

static int imx_rpmsg_pcm_resume(struct device *dev)
{
	struct rpmsg_info *info = dev_get_drvdata(dev);
	struct rpmsg_msg *rpmsg_tx;
	struct rpmsg_msg *rpmsg_rx;

	rpmsg_tx = &info->msg[TX_RESUME];
	rpmsg_rx = &info->msg[RX_RESUME];

	rpmsg_tx->s_msg.header.cmd = TX_RESUME;
	info->send_message(rpmsg_tx, info);

	rpmsg_rx->s_msg.header.cmd = RX_RESUME;
	info->send_message(rpmsg_rx, info);

	return 0;
}
#endif /* CONFIG_PM_SLEEP */

static const struct dev_pm_ops imx_rpmsg_pcm_pm_ops = {
	SET_RUNTIME_PM_OPS(imx_rpmsg_pcm_runtime_suspend,
			   imx_rpmsg_pcm_runtime_resume,
			   NULL)
	SET_SYSTEM_SLEEP_PM_OPS(imx_rpmsg_pcm_suspend,
				imx_rpmsg_pcm_resume)
};

static struct platform_driver imx_pcm_rpmsg_driver = {
	.probe  = imx_rpmsg_pcm_probe,
	.remove	= imx_rpmsg_pcm_remove,
	.driver = {
		.name = IMX_PCM_DRV_NAME,
		.pm = &imx_rpmsg_pcm_pm_ops,
	},
};
module_platform_driver(imx_pcm_rpmsg_driver);

MODULE_DESCRIPTION("Freescale SoC Audio RPMSG PCM interface");
MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang@nxp.com>");
MODULE_ALIAS("platform:" IMX_PCM_DRV_NAME);
MODULE_LICENSE("GPL v2");
