ASoC: fsl: Use guard() for mutex & spin locks

bui duc phuc <phucduc.bui@gmail.com> says:

This series converts mutex and spinlock handling in the FSL sound drivers
to use guard() helpers.
The changes are code cleanup only and should have no functional impact.

Compile tested only.

Link: https://patch.msgid.link/20260615093824.115751-1-phucduc.bui@gmail.com
This commit is contained in:
Mark Brown 2026-06-29 19:19:04 +01:00
commit 9cdb8f53be
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
11 changed files with 121 additions and 186 deletions

View File

@ -222,10 +222,9 @@ static int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair)
enum asrc_pair_index index = ASRC_INVALID_PAIR;
struct fsl_asrc *asrc = pair->asrc;
struct device *dev = &asrc->pdev->dev;
unsigned long lock_flags;
int i, ret = 0;
spin_lock_irqsave(&asrc->lock, lock_flags);
guard(spinlock_irqsave)(&asrc->lock);
for (i = ASRC_PAIR_A; i < ASRC_PAIR_MAX_NUM; i++) {
if (asrc->pair[i] != NULL)
@ -250,8 +249,6 @@ static int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair)
pair->index = index;
}
spin_unlock_irqrestore(&asrc->lock, lock_flags);
return ret;
}
@ -265,19 +262,16 @@ static void fsl_asrc_release_pair(struct fsl_asrc_pair *pair)
{
struct fsl_asrc *asrc = pair->asrc;
enum asrc_pair_index index = pair->index;
unsigned long lock_flags;
/* Make sure the pair is disabled */
regmap_update_bits(asrc->regmap, REG_ASRCTR,
ASRCTR_ASRCEi_MASK(index), 0);
spin_lock_irqsave(&asrc->lock, lock_flags);
guard(spinlock_irqsave)(&asrc->lock);
asrc->channel_avail += pair->channels;
asrc->pair[index] = NULL;
pair->error = 0;
spin_unlock_irqrestore(&asrc->lock, lock_flags);
}
/**

View File

@ -286,7 +286,6 @@ static int fsl_audmix_dai_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
struct fsl_audmix *priv = snd_soc_dai_get_drvdata(dai);
unsigned long lock_flags;
/* Capture stream shall not be handled */
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
@ -296,16 +295,14 @@ static int fsl_audmix_dai_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
spin_lock_irqsave(&priv->lock, lock_flags);
priv->tdms |= BIT(dai->driver->id);
spin_unlock_irqrestore(&priv->lock, lock_flags);
scoped_guard(spinlock_irqsave, &priv->lock)
priv->tdms |= BIT(dai->driver->id);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
spin_lock_irqsave(&priv->lock, lock_flags);
priv->tdms &= ~BIT(dai->driver->id);
spin_unlock_irqrestore(&priv->lock, lock_flags);
scoped_guard(spinlock_irqsave, &priv->lock)
priv->tdms &= ~BIT(dai->driver->id);
break;
default:
return -EINVAL;

View File

@ -1025,7 +1025,6 @@ static int fsl_easrc_config_context(struct fsl_asrc *easrc, unsigned int ctx_id)
struct fsl_easrc_ctx_priv *ctx_priv;
struct fsl_asrc_pair *ctx;
struct device *dev;
unsigned long lock_flags;
int ret;
if (!easrc)
@ -1053,9 +1052,8 @@ static int fsl_easrc_config_context(struct fsl_asrc *easrc, unsigned int ctx_id)
if (ret)
return ret;
spin_lock_irqsave(&easrc->lock, lock_flags);
ret = fsl_easrc_config_slot(easrc, ctx->index);
spin_unlock_irqrestore(&easrc->lock, lock_flags);
scoped_guard(spinlock_irqsave, &easrc->lock)
ret = fsl_easrc_config_slot(easrc, ctx->index);
if (ret)
return ret;
@ -1301,13 +1299,12 @@ static int fsl_easrc_request_context(int channels, struct fsl_asrc_pair *ctx)
enum asrc_pair_index index = ASRC_INVALID_PAIR;
struct fsl_asrc *easrc = ctx->asrc;
struct device *dev;
unsigned long lock_flags;
int ret = 0;
int i;
dev = &easrc->pdev->dev;
spin_lock_irqsave(&easrc->lock, lock_flags);
guard(spinlock_irqsave)(&easrc->lock);
for (i = ASRC_PAIR_A; i < EASRC_CTX_MAX_NUM; i++) {
if (easrc->pair[i])
@ -1331,8 +1328,6 @@ static int fsl_easrc_request_context(int channels, struct fsl_asrc_pair *ctx)
easrc->channel_avail -= channels;
}
spin_unlock_irqrestore(&easrc->lock, lock_flags);
return ret;
}
@ -1343,7 +1338,6 @@ static int fsl_easrc_request_context(int channels, struct fsl_asrc_pair *ctx)
*/
static void fsl_easrc_release_context(struct fsl_asrc_pair *ctx)
{
unsigned long lock_flags;
struct fsl_asrc *easrc;
if (!ctx)
@ -1351,14 +1345,12 @@ static void fsl_easrc_release_context(struct fsl_asrc_pair *ctx)
easrc = ctx->asrc;
spin_lock_irqsave(&easrc->lock, lock_flags);
guard(spinlock_irqsave)(&easrc->lock);
fsl_easrc_release_slot(easrc, ctx->index);
easrc->channel_avail += ctx->channels;
easrc->pair[ctx->index] = NULL;
spin_unlock_irqrestore(&easrc->lock, lock_flags);
}
/*
@ -2292,15 +2284,13 @@ static int fsl_easrc_runtime_suspend(struct device *dev)
{
struct fsl_asrc *easrc = dev_get_drvdata(dev);
struct fsl_easrc_priv *easrc_priv = easrc->private;
unsigned long lock_flags;
regcache_cache_only(easrc->regmap, true);
clk_disable_unprepare(easrc->mem_clk);
spin_lock_irqsave(&easrc->lock, lock_flags);
easrc_priv->firmware_loaded = 0;
spin_unlock_irqrestore(&easrc->lock, lock_flags);
scoped_guard(spinlock_irqsave, &easrc->lock)
easrc_priv->firmware_loaded = 0;
return 0;
}
@ -2311,7 +2301,6 @@ static int fsl_easrc_runtime_resume(struct device *dev)
struct fsl_easrc_priv *easrc_priv = easrc->private;
struct fsl_easrc_ctx_priv *ctx_priv;
struct fsl_asrc_pair *ctx;
unsigned long lock_flags;
int ret;
int i;
@ -2323,13 +2312,11 @@ static int fsl_easrc_runtime_resume(struct device *dev)
regcache_mark_dirty(easrc->regmap);
regcache_sync(easrc->regmap);
spin_lock_irqsave(&easrc->lock, lock_flags);
if (easrc_priv->firmware_loaded) {
spin_unlock_irqrestore(&easrc->lock, lock_flags);
goto skip_load;
scoped_guard(spinlock_irqsave, &easrc->lock) {
if (easrc_priv->firmware_loaded)
return 0;
easrc_priv->firmware_loaded = 1;
}
easrc_priv->firmware_loaded = 1;
spin_unlock_irqrestore(&easrc->lock, lock_flags);
ret = fsl_easrc_get_firmware(easrc);
if (ret) {
@ -2377,9 +2364,6 @@ static int fsl_easrc_runtime_resume(struct device *dev)
goto disable_mem_clk;
}
skip_load:
return 0;
disable_mem_clk:
clk_disable_unprepare(easrc->mem_clk);
return ret;

View File

@ -709,10 +709,9 @@ static void fsl_esai_hw_reset(struct work_struct *work)
{
struct fsl_esai *esai_priv = container_of(work, struct fsl_esai, work);
bool tx = true, rx = false, enabled[2];
unsigned long lock_flags;
u32 tfcr, rfcr;
spin_lock_irqsave(&esai_priv->lock, lock_flags);
guard(spinlock_irqsave)(&esai_priv->lock);
/* Save the registers */
regmap_read(esai_priv->regmap, REG_ESAI_TFCR, &tfcr);
regmap_read(esai_priv->regmap, REG_ESAI_RFCR, &rfcr);
@ -750,8 +749,6 @@ static void fsl_esai_hw_reset(struct work_struct *work)
fsl_esai_trigger_start(esai_priv, tx);
if (enabled[rx])
fsl_esai_trigger_start(esai_priv, rx);
spin_unlock_irqrestore(&esai_priv->lock, lock_flags);
}
static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
@ -759,7 +756,6 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
{
struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
unsigned long lock_flags;
esai_priv->channels[tx] = substream->runtime->channels;
@ -767,16 +763,14 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
spin_lock_irqsave(&esai_priv->lock, lock_flags);
fsl_esai_trigger_start(esai_priv, tx);
spin_unlock_irqrestore(&esai_priv->lock, lock_flags);
scoped_guard(spinlock_irqsave, &esai_priv->lock)
fsl_esai_trigger_start(esai_priv, tx);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
spin_lock_irqsave(&esai_priv->lock, lock_flags);
fsl_esai_trigger_stop(esai_priv, tx);
spin_unlock_irqrestore(&esai_priv->lock, lock_flags);
scoped_guard(spinlock_irqsave, &esai_priv->lock)
fsl_esai_trigger_stop(esai_priv, tx);
break;
default:
return -EINVAL;

View File

@ -853,17 +853,15 @@ static int fsl_spdif_subcode_get(struct snd_kcontrol *kcontrol,
struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
unsigned long flags;
int ret = -EAGAIN;
spin_lock_irqsave(&ctrl->ctl_lock, flags);
guard(spinlock_irqsave)(&ctrl->ctl_lock);
if (ctrl->ready_buf) {
int idx = (ctrl->ready_buf - 1) * SPDIF_UBITS_SIZE;
memcpy(&ucontrol->value.iec958.subcode[0],
&ctrl->subcode[idx], SPDIF_UBITS_SIZE);
ret = 0;
}
spin_unlock_irqrestore(&ctrl->ctl_lock, flags);
return ret;
}
@ -885,17 +883,15 @@ static int fsl_spdif_qget(struct snd_kcontrol *kcontrol,
struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
unsigned long flags;
int ret = -EAGAIN;
spin_lock_irqsave(&ctrl->ctl_lock, flags);
guard(spinlock_irqsave)(&ctrl->ctl_lock);
if (ctrl->ready_buf) {
int idx = (ctrl->ready_buf - 1) * SPDIF_QSUB_SIZE;
memcpy(&ucontrol->value.bytes.data[0],
&ctrl->qsub[idx], SPDIF_QSUB_SIZE);
ret = 0;
}
spin_unlock_irqrestore(&ctrl->ctl_lock, flags);
return ret;
}

View File

@ -1218,13 +1218,13 @@ static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
if (reg > 0x7f)
return;
mutex_lock(&fsl_ac97_data->ac97_reg_lock);
guard(mutex)(&fsl_ac97_data->ac97_reg_lock);
ret = clk_prepare_enable(fsl_ac97_data->clk);
if (ret) {
pr_err("ac97 write clk_prepare_enable failed: %d\n",
ret);
goto ret_unlock;
return;
}
lreg = reg << 12;
@ -1238,9 +1238,6 @@ static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
udelay(100);
clk_disable_unprepare(fsl_ac97_data->clk);
ret_unlock:
mutex_unlock(&fsl_ac97_data->ac97_reg_lock);
}
static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97,
@ -1252,12 +1249,12 @@ static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97,
unsigned int lreg;
int ret;
mutex_lock(&fsl_ac97_data->ac97_reg_lock);
guard(mutex)(&fsl_ac97_data->ac97_reg_lock);
ret = clk_prepare_enable(fsl_ac97_data->clk);
if (ret) {
pr_err("ac97 read clk_prepare_enable failed: %d\n", ret);
goto ret_unlock;
return val;
}
lreg = (reg & 0x7f) << 12;
@ -1272,8 +1269,6 @@ static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97,
clk_disable_unprepare(fsl_ac97_data->clk);
ret_unlock:
mutex_unlock(&fsl_ac97_data->ac97_reg_lock);
return val;
}

View File

@ -797,10 +797,9 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
{
struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
unsigned long lock_flags;
int ret = 0;
spin_lock_irqsave(&xcvr->lock, lock_flags);
guard(spinlock_irqsave)(&xcvr->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@ -812,7 +811,7 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
FSL_XCVR_EXT_CTRL_DPTH_RESET(tx));
if (ret < 0) {
dev_err(dai->dev, "Failed to set DPATH RESET: %d\n", ret);
goto release_lock;
return ret;
}
if (tx) {
@ -824,7 +823,7 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
FSL_XCVR_ISR_CMDC_TX_EN);
if (ret < 0) {
dev_err(dai->dev, "err updating isr %d\n", ret);
goto release_lock;
return ret;
}
fallthrough;
case FSL_XCVR_MODE_SPDIF:
@ -833,7 +832,7 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
FSL_XCVR_TX_DPTH_CTRL_STRT_DATA_TX);
if (ret < 0) {
dev_err(dai->dev, "Failed to start DATA_TX: %d\n", ret);
goto release_lock;
return ret;
}
break;
}
@ -844,14 +843,14 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
FSL_XCVR_EXT_CTRL_DMA_DIS(tx), 0);
if (ret < 0) {
dev_err(dai->dev, "Failed to enable DMA: %d\n", ret);
goto release_lock;
return ret;
}
ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0,
FSL_XCVR_IRQ_EARC_ALL, FSL_XCVR_IRQ_EARC_ALL);
if (ret < 0) {
dev_err(dai->dev, "Error while setting IER0: %d\n", ret);
goto release_lock;
return ret;
}
/* clear DPATH RESET */
@ -860,7 +859,7 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
0);
if (ret < 0) {
dev_err(dai->dev, "Failed to clear DPATH RESET: %d\n", ret);
goto release_lock;
return ret;
}
break;
@ -873,14 +872,14 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
FSL_XCVR_EXT_CTRL_DMA_DIS(tx));
if (ret < 0) {
dev_err(dai->dev, "Failed to disable DMA: %d\n", ret);
goto release_lock;
return ret;
}
ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0,
FSL_XCVR_IRQ_EARC_ALL, 0);
if (ret < 0) {
dev_err(dai->dev, "Failed to clear IER0: %d\n", ret);
goto release_lock;
return ret;
}
if (tx) {
@ -891,7 +890,7 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
FSL_XCVR_TX_DPTH_CTRL_STRT_DATA_TX);
if (ret < 0) {
dev_err(dai->dev, "Failed to stop DATA_TX: %d\n", ret);
goto release_lock;
return ret;
}
if (xcvr->soc_data->spdif_only)
break;
@ -905,7 +904,7 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
if (ret < 0) {
dev_err(dai->dev,
"Err updating ISR %d\n", ret);
goto release_lock;
return ret;
}
break;
}
@ -916,8 +915,6 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
break;
}
release_lock:
spin_unlock_irqrestore(&xcvr->lock, lock_flags);
return ret;
}
@ -1448,11 +1445,10 @@ static void reset_rx_work(struct work_struct *work)
{
struct fsl_xcvr *xcvr = container_of(work, struct fsl_xcvr, work_rst);
struct device *dev = &xcvr->pdev->dev;
unsigned long lock_flags;
u32 ext_ctrl;
dev_dbg(dev, "reset rx path\n");
spin_lock_irqsave(&xcvr->lock, lock_flags);
guard(spinlock_irqsave)(&xcvr->lock);
regmap_read(xcvr->regmap, FSL_XCVR_EXT_CTRL, &ext_ctrl);
if (!(ext_ctrl & FSL_XCVR_EXT_CTRL_DMA_RD_DIS)) {
@ -1469,7 +1465,6 @@ static void reset_rx_work(struct work_struct *work)
FSL_XCVR_EXT_CTRL_RX_DPTH_RESET,
0);
}
spin_unlock_irqrestore(&xcvr->lock, lock_flags);
}
static irqreturn_t irq0_isr(int irq, void *devid)

View File

@ -22,7 +22,6 @@ static int imx_audio_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,
struct rpmsg_r_msg *r_msg = (struct rpmsg_r_msg *)data;
struct rpmsg_info *info;
struct rpmsg_msg *msg;
unsigned long flags;
if (!rpmsg->rpmsg_pdev)
return 0;
@ -37,21 +36,21 @@ static int imx_audio_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,
/* TYPE C is notification from M core */
switch (r_msg->header.cmd) {
case TX_PERIOD_DONE:
spin_lock_irqsave(&info->lock[TX], flags);
msg = &info->msg[TX_PERIOD_DONE + MSG_TYPE_A_NUM];
msg->r_msg.param.buffer_tail =
r_msg->param.buffer_tail;
msg->r_msg.param.buffer_tail %= info->num_period[TX];
spin_unlock_irqrestore(&info->lock[TX], flags);
scoped_guard(spinlock_irqsave, &info->lock[TX]) {
msg = &info->msg[TX_PERIOD_DONE + MSG_TYPE_A_NUM];
msg->r_msg.param.buffer_tail =
r_msg->param.buffer_tail;
msg->r_msg.param.buffer_tail %= info->num_period[TX];
}
info->callback[TX](info->callback_param[TX]);
break;
case RX_PERIOD_DONE:
spin_lock_irqsave(&info->lock[RX], flags);
msg = &info->msg[RX_PERIOD_DONE + MSG_TYPE_A_NUM];
msg->r_msg.param.buffer_tail =
r_msg->param.buffer_tail;
msg->r_msg.param.buffer_tail %= info->num_period[1];
spin_unlock_irqrestore(&info->lock[RX], flags);
scoped_guard(spinlock_irqsave, &info->lock[RX]) {
msg = &info->msg[RX_PERIOD_DONE + MSG_TYPE_A_NUM];
msg->r_msg.param.buffer_tail =
r_msg->param.buffer_tail;
msg->r_msg.param.buffer_tail %= info->num_period[1];
}
info->callback[RX](info->callback_param[RX]);
break;
default:

View File

@ -39,10 +39,9 @@ static int imx_rpmsg_pcm_send_message(struct rpmsg_msg *msg,
struct rpmsg_device *rpdev = info->rpdev;
int ret = 0;
mutex_lock(&info->msg_lock);
guard(mutex)(&info->msg_lock);
if (!rpdev) {
dev_err(info->dev, "rpmsg channel not ready\n");
mutex_unlock(&info->msg_lock);
return -EINVAL;
}
@ -55,15 +54,12 @@ static int imx_rpmsg_pcm_send_message(struct rpmsg_msg *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);
if (msg->s_msg.header.type == MSG_TYPE_C)
return 0;
}
/* wait response from rpmsg */
ret = wait_for_completion_timeout(&info->cmd_complete,
@ -71,7 +67,6 @@ static int imx_rpmsg_pcm_send_message(struct rpmsg_msg *msg,
if (!ret) {
dev_err(&rpdev->dev, "rpmsg_send cmd %d timeout!\n",
msg->s_msg.header.cmd);
mutex_unlock(&info->msg_lock);
return -ETIMEDOUT;
}
@ -100,8 +95,6 @@ static int imx_rpmsg_pcm_send_message(struct rpmsg_msg *msg,
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;
}
@ -109,14 +102,13 @@ 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);
guard(spinlock_irqsave)(&info->wq_lock);
if (info->work_write_index != info->work_read_index) {
int index = info->work_write_index;
@ -130,7 +122,6 @@ static int imx_rpmsg_insert_workqueue(struct snd_pcm_substream *substream,
info->msg_drop_count[substream->stream]++;
ret = -EPIPE;
}
spin_unlock_irqrestore(&info->wq_lock, flags);
return ret;
}
@ -523,7 +514,6 @@ static int imx_rpmsg_pcm_ack(struct snd_soc_component *component,
snd_pcm_sframes_t avail;
struct timer_list *timer;
struct rpmsg_msg *msg;
unsigned long flags;
int buffer_tail = 0;
int written_num;
@ -553,11 +543,11 @@ static int imx_rpmsg_pcm_ack(struct snd_soc_component *component,
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);
scoped_guard(spinlock_irqsave, &info->lock[substream->stream]) {
memcpy(&info->notify[substream->stream], msg,
sizeof(struct rpmsg_s_msg));
info->notify_updated[substream->stream] = true;
}
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
avail = snd_pcm_playback_hw_avail(runtime);
@ -641,7 +631,7 @@ static void imx_rpmsg_pcm_work(struct work_struct *work)
bool is_notification = false;
struct rpmsg_info *info;
struct rpmsg_msg msg;
unsigned long flags;
bool updated;
work_of_rpmsg = container_of(work, struct work_of_rpmsg, work);
info = work_of_rpmsg->info;
@ -652,25 +642,26 @@ static void imx_rpmsg_pcm_work(struct work_struct *work)
* 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);
scoped_guard(spinlock_irqsave, &info->lock[TX]) {
updated = info->notify_updated[TX];
if (updated) {
memcpy(&msg, &info->notify[TX], sizeof(struct rpmsg_s_msg));
info->notify_updated[TX] = false;
}
}
if (updated)
info->send_message(&msg, info);
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);
scoped_guard(spinlock_irqsave, &info->lock[RX]) {
updated = info->notify_updated[RX];
if (updated) {
memcpy(&msg, &info->notify[RX], sizeof(struct rpmsg_s_msg));
info->notify_updated[RX] = false;
}
}
if (updated)
info->send_message(&msg, info);
/* Skip the notification message for it has been processed above */
if (work_of_rpmsg->msg.s_msg.header.type == MSG_TYPE_C &&
@ -682,10 +673,10 @@ static void imx_rpmsg_pcm_work(struct work_struct *work)
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);
scoped_guard(spinlock_irqsave, &info->wq_lock) {
info->work_read_index++;
info->work_read_index %= WORK_MAX_NUM;
}
}
static int imx_rpmsg_pcm_probe(struct platform_device *pdev)

View File

@ -77,18 +77,20 @@ static irqreturn_t psc_dma_bcom_irq(int irq, void *_psc_dma_stream)
{
struct psc_dma_stream *s = _psc_dma_stream;
spin_lock(&s->psc_dma->lock);
/* For each finished period, dequeue the completed period buffer
* and enqueue a new one in it's place. */
while (bcom_buffer_done(s->bcom_task)) {
bcom_retrieve_buffer(s->bcom_task, NULL, NULL);
scoped_guard(spinlock, &s->psc_dma->lock) {
/*
* For each finished period, dequeue the completed period buffer
* and enqueue a new one in its place
*/
while (bcom_buffer_done(s->bcom_task)) {
bcom_retrieve_buffer(s->bcom_task, NULL, NULL);
s->period_current = (s->period_current+1) % s->runtime->periods;
s->period_count++;
s->period_current = (s->period_current+1) % s->runtime->periods;
s->period_count++;
psc_dma_bcom_enqueue_next_buffer(s);
psc_dma_bcom_enqueue_next_buffer(s);
}
}
spin_unlock(&s->psc_dma->lock);
/* If the stream is active, then also inform the PCM middle layer
* of the period finished event. */
@ -116,7 +118,6 @@ static int psc_dma_trigger(struct snd_soc_component *component,
struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
u16 imr;
unsigned long flags;
int i;
switch (cmd) {
@ -135,19 +136,18 @@ static int psc_dma_trigger(struct snd_soc_component *component,
/* Fill up the bestcomm bd queue and enable DMA.
* This will begin filling the PSC's fifo.
*/
spin_lock_irqsave(&psc_dma->lock, flags);
scoped_guard(spinlock_irqsave, &psc_dma->lock) {
if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
bcom_gen_bd_rx_reset(s->bcom_task);
else
bcom_gen_bd_tx_reset(s->bcom_task);
if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
bcom_gen_bd_rx_reset(s->bcom_task);
else
bcom_gen_bd_tx_reset(s->bcom_task);
for (i = 0; i < runtime->periods; i++)
if (!bcom_queue_full(s->bcom_task))
psc_dma_bcom_enqueue_next_buffer(s);
for (i = 0; i < runtime->periods; i++)
if (!bcom_queue_full(s->bcom_task))
psc_dma_bcom_enqueue_next_buffer(s);
bcom_enable(s->bcom_task);
spin_unlock_irqrestore(&psc_dma->lock, flags);
bcom_enable(s->bcom_task);
}
out_8(&regs->command, MPC52xx_PSC_RST_ERR_STAT);
@ -158,13 +158,13 @@ static int psc_dma_trigger(struct snd_soc_component *component,
substream->pstr->stream, s->period_count);
s->active = 0;
spin_lock_irqsave(&psc_dma->lock, flags);
bcom_disable(s->bcom_task);
if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
bcom_gen_bd_rx_reset(s->bcom_task);
else
bcom_gen_bd_tx_reset(s->bcom_task);
spin_unlock_irqrestore(&psc_dma->lock, flags);
scoped_guard(spinlock_irqsave, &psc_dma->lock) {
bcom_disable(s->bcom_task);
if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
bcom_gen_bd_rx_reset(s->bcom_task);
else
bcom_gen_bd_tx_reset(s->bcom_task);
}
break;

View File

@ -31,14 +31,13 @@ static unsigned short psc_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
int status;
unsigned int val;
mutex_lock(&psc_dma->mutex);
guard(mutex)(&psc_dma->mutex);
/* Wait for command send status zero = ready */
status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) &
MPC52xx_PSC_SR_CMDSEND), 100, 0);
if (status == 0) {
pr_err("timeout on ac97 bus (rdy)\n");
mutex_unlock(&psc_dma->mutex);
return -ENODEV;
}
@ -54,19 +53,16 @@ static unsigned short psc_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
if (status == 0) {
pr_err("timeout on ac97 read (val) %x\n",
in_be16(&psc_dma->psc_regs->sr_csr.status));
mutex_unlock(&psc_dma->mutex);
return -ENODEV;
}
/* Get the data */
val = in_be32(&psc_dma->psc_regs->ac97_data);
if (((val >> 24) & 0x7f) != reg) {
pr_err("reg echo error on ac97 read\n");
mutex_unlock(&psc_dma->mutex);
return -ENODEV;
}
val = (val >> 8) & 0xffff;
mutex_unlock(&psc_dma->mutex);
return (unsigned short) val;
}
@ -75,52 +71,46 @@ static void psc_ac97_write(struct snd_ac97 *ac97,
{
int status;
mutex_lock(&psc_dma->mutex);
guard(mutex)(&psc_dma->mutex);
/* Wait for command status zero = ready */
status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) &
MPC52xx_PSC_SR_CMDSEND), 100, 0);
if (status == 0) {
pr_err("timeout on ac97 bus (write)\n");
goto out;
return;
}
/* Write data */
out_be32(&psc_dma->psc_regs->ac97_cmd,
((reg & 0x7f) << 24) | (val << 8));
out:
mutex_unlock(&psc_dma->mutex);
}
static void psc_ac97_warm_reset(struct snd_ac97 *ac97)
{
struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
mutex_lock(&psc_dma->mutex);
guard(mutex)(&psc_dma->mutex);
out_be32(&regs->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_AWR);
udelay(3);
out_be32(&regs->sicr, psc_dma->sicr);
mutex_unlock(&psc_dma->mutex);
}
static void psc_ac97_cold_reset(struct snd_ac97 *ac97)
{
struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
mutex_lock(&psc_dma->mutex);
dev_dbg(psc_dma->dev, "cold reset\n");
scoped_guard(mutex, &psc_dma->mutex) {
dev_dbg(psc_dma->dev, "cold reset\n");
mpc5200_psc_ac97_gpio_reset(psc_dma->id);
mpc5200_psc_ac97_gpio_reset(psc_dma->id);
/* Notify the PSC that a reset has occurred */
out_be32(&regs->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_ACRB);
/* Notify the PSC that a reset has occurred */
out_be32(&regs->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_ACRB);
/* Re-enable RX and TX */
out_8(&regs->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
mutex_unlock(&psc_dma->mutex);
/* Re-enable RX and TX */
out_8(&regs->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
}
usleep_range(1000, 2000);
psc_ac97_warm_reset(ac97);