struct work_of_rpmsg *work_of_rpmsg;
struct i2s_info *i2s_info;
bool is_period_done = false;
+ unsigned long flags;
+ struct i2s_rpmsg msg;
work_of_rpmsg = container_of(work, struct work_of_rpmsg, work);
i2s_info = work_of_rpmsg->i2s_info;
+ spin_lock_irqsave(&i2s_info->lock[0], flags);
if (i2s_info->period_done_msg_enabled[0]) {
- i2s_send_message(&i2s_info->period_done_msg[0], i2s_info);
+ memcpy(&msg, &i2s_info->period_done_msg[0], sizeof(struct i2s_rpmsg_s));
i2s_info->period_done_msg_enabled[0] = false;
- }
+ spin_unlock_irqrestore(&i2s_info->lock[0], flags);
+
+ i2s_send_message(&msg, i2s_info);
+ } else
+ spin_unlock_irqrestore(&i2s_info->lock[0], flags);
if (i2s_info->period_done_msg_enabled[1]) {
i2s_send_message(&i2s_info->period_done_msg[1], i2s_info);
if (!is_period_done)
i2s_send_message(&work_of_rpmsg->msg, i2s_info);
+ spin_lock_irqsave(&i2s_info->wq_lock, flags);
i2s_info->work_read_index++;
i2s_info->work_read_index %= WORK_MAX_NUM;
+ spin_unlock_irqrestore(&i2s_info->wq_lock, flags);
}
static int fsl_rpmsg_i2s_probe(struct platform_device *pdev)
mutex_init(&i2s_info->i2c_lock);
spin_lock_init(&i2s_info->lock[0]);
spin_lock_init(&i2s_info->lock[1]);
+ spin_lock_init(&i2s_info->wq_lock);
if (of_device_is_compatible(pdev->dev.of_node,
"fsl,imx7ulp-rpmsg-i2s")) {
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;
- int index = i2s_info->work_write_index;
+ unsigned long flags;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
rpmsg = &i2s_info->rpmsg[I2S_TX_PERIOD_DONE + I2S_TYPE_A_NUM];
else
rpmsg->send_msg.header.cmd = I2S_RX_PERIOD_DONE;
+ spin_lock_irqsave(&i2s_info->wq_lock, flags);
if (i2s_info->work_write_index != i2s_info->work_read_index) {
+ int index = i2s_info->work_write_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 %= WORK_MAX_NUM;
} else
i2s_info->msg_drop_count[substream->stream]++;
+ spin_unlock_irqrestore(&i2s_info->wq_lock, flags);
}
static int imx_rpmsg_pcm_open(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;
- int index = i2s_info->work_write_index;
+ unsigned long flags;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
rpmsg = &i2s_info->rpmsg[I2S_TX_BUFFER];
rpmsg->send_msg.param.buffer_size /
rpmsg->send_msg.param.period_size;
+ i2s_info->callback[substream->stream] = imx_rpmsg_pcm_dma_complete;
+ i2s_info->callback_param[substream->stream] = substream;
+
+ spin_lock_irqsave(&i2s_info->wq_lock, flags);
if (i2s_info->work_write_index != i2s_info->work_read_index) {
+ int index = i2s_info->work_write_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
+ spin_unlock_irqrestore(&i2s_info->wq_lock, flags);
+ } else {
+ spin_unlock_irqrestore(&i2s_info->wq_lock, flags);
return -EPIPE;
+ }
- i2s_info->callback[substream->stream] = imx_rpmsg_pcm_dma_complete;
- i2s_info->callback_param[substream->stream] = substream;
return 0;
}
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;
- int index = i2s_info->work_write_index;
+ unsigned long flags;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
rpmsg = &i2s_info->rpmsg[I2S_TX_START];
else
rpmsg->send_msg.header.cmd = I2S_RX_START;
+ spin_lock_irqsave(&i2s_info->wq_lock, flags);
if (i2s_info->work_write_index != i2s_info->work_read_index) {
+ int index = i2s_info->work_write_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
+ spin_unlock_irqrestore(&i2s_info->wq_lock, flags);
+ } else {
+ spin_unlock_irqrestore(&i2s_info->wq_lock, flags);
return -EPIPE;
+ }
return 0;
}
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;
- int index = i2s_info->work_write_index;
+ unsigned long flags;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
rpmsg = &i2s_info->rpmsg[I2S_TX_RESTART];
else
rpmsg->send_msg.header.cmd = I2S_RX_RESTART;
+ spin_lock_irqsave(&i2s_info->wq_lock, flags);
if (i2s_info->work_write_index != i2s_info->work_read_index) {
+ int index = i2s_info->work_write_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
+ spin_unlock_irqrestore(&i2s_info->wq_lock, flags);
+ } else {
+ spin_unlock_irqrestore(&i2s_info->wq_lock, flags);
return -EPIPE;
-
+ }
return 0;
}
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;
- int index = i2s_info->work_write_index;
+ unsigned long flags;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
rpmsg = &i2s_info->rpmsg[I2S_TX_PAUSE];
else
rpmsg->send_msg.header.cmd = I2S_RX_PAUSE;
+ spin_lock_irqsave(&i2s_info->wq_lock, flags);
if (i2s_info->work_write_index != i2s_info->work_read_index) {
+ int index = i2s_info->work_write_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
+ spin_unlock_irqrestore(&i2s_info->wq_lock, flags);
+ } else {
+ spin_unlock_irqrestore(&i2s_info->wq_lock, flags);
return -EPIPE;
-
+ }
return 0;
}
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;
- int index = i2s_info->work_write_index;
int cmd;
+ unsigned long flags;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
rpmsg = &i2s_info->rpmsg[I2S_TX_TERMINATE];
del_timer(&i2s_info->stream_timer[substream->stream].timer);
+ spin_lock_irqsave(&i2s_info->wq_lock, flags);
if (i2s_info->work_write_index != i2s_info->work_read_index) {
+ int index = i2s_info->work_write_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
+ spin_unlock_irqrestore(&i2s_info->wq_lock, flags);
+ } else {
+ spin_unlock_irqrestore(&i2s_info->wq_lock, flags);
return -EPIPE;
+ }
return 0;
}
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;
- int index = i2s_info->work_write_index;
int buffer_tail = 0;
int writen_num = 0;
snd_pcm_sframes_t avail;
+ unsigned long flags;
if (!rpmsg_i2s->force_lpa)
return 0;
writen_num += runtime->periods;
rpmsg->send_msg.param.buffer_tail = buffer_tail;
+
+ spin_lock_irqsave(&i2s_info->lock[substream->stream], flags);
memcpy(&i2s_info->period_done_msg[substream->stream], rpmsg,
sizeof(struct i2s_rpmsg_s));
+
i2s_info->period_done_msg_enabled[substream->stream] = true;
+ spin_unlock_irqrestore(&i2s_info->lock[substream->stream], flags);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
avail = snd_pcm_playback_hw_avail(runtime);
avail = snd_pcm_capture_hw_avail(runtime);
if ((avail - writen_num * runtime->period_size) <= runtime->period_size) {
+ spin_lock_irqsave(&i2s_info->wq_lock, flags);
if (i2s_info->work_write_index != i2s_info->work_read_index) {
+ int index = i2s_info->work_write_index;
memcpy(&i2s_info->work_list[index].msg, rpmsg,
sizeof(struct i2s_rpmsg_s));
queue_work(i2s_info->rpmsg_wq,
i2s_info->work_write_index %= WORK_MAX_NUM;
} else
i2s_info->msg_drop_count[substream->stream]++;
+ spin_unlock_irqrestore(&i2s_info->wq_lock, flags);
} else {
if (rpmsg_i2s->force_lpa && !timer_pending(&i2s_info->stream_timer[substream->stream].timer)) {
int time_msec;