From 1dc77c2ec5c065acbca5b84dfcdf4ce9214f99d4 Mon Sep 17 00:00:00 2001 From: Masayuki Ishikawa Date: Mon, 15 Feb 2021 15:24:28 +0900 Subject: [PATCH] drivers: audio: Introduce a driver-specific spinlock to cxd56.c Summary: - This commit introduces a driver-specific spinlock to cxd56.c to improve performance in SMP mode. Impact: - cxd56.c in SMP mode only Testing: - Tested with nxplayer and nxrecorder with the following configs - spresense:wifi, spresense:wifi_smp Signed-off-by: Masayuki Ishikawa --- drivers/audio/cxd56.c | 48 +++++++++++++++++++++---------------------- drivers/audio/cxd56.h | 2 ++ 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/drivers/audio/cxd56.c b/drivers/audio/cxd56.c index aaf330802d..296b1162e8 100644 --- a/drivers/audio/cxd56.c +++ b/drivers/audio/cxd56.c @@ -1275,7 +1275,7 @@ static void _process_audio_with_src(cxd56_dmahandle_t hdl, uint16_t err_code) /* Trigger new DMA job */ - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&dev->lock); if (err_code == CXD56_AUDIO_ECODE_DMA_TRANS) { @@ -1286,10 +1286,10 @@ static void _process_audio_with_src(cxd56_dmahandle_t hdl, uint16_t err_code) { msg.msg_id = AUDIO_MSG_STOP; msg.u.data = 0; - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&dev->lock, flags); ret = file_mq_send(&dev->mq, (FAR const char *)&msg, sizeof(msg), CONFIG_CXD56_MSG_PRIO); - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&dev->lock); if (ret != OK) { auderr("ERROR: file_mq_send to stop failed (%d)\n", ret); @@ -1310,9 +1310,9 @@ static void _process_audio_with_src(cxd56_dmahandle_t hdl, uint16_t err_code) struct ap_buffer_s *apb; apb = dq_get(&dev->up_runq); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&dev->lock, flags); dev->dev.upper(dev->dev.priv, AUDIO_CALLBACK_DEQUEUE, apb, OK); - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&dev->lock); /* End of data? */ @@ -1320,10 +1320,10 @@ static void _process_audio_with_src(cxd56_dmahandle_t hdl, uint16_t err_code) { msg.msg_id = AUDIO_MSG_STOP; msg.u.data = 0; - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&dev->lock, flags); ret = file_mq_send(&dev->mq, (FAR const char *)&msg, sizeof(msg), CONFIG_CXD56_MSG_PRIO); - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&dev->lock); if (ret != OK) { auderr("ERROR: file_mq_send to stop failed (%d)\n", ret); @@ -1340,17 +1340,17 @@ static void _process_audio_with_src(cxd56_dmahandle_t hdl, uint16_t err_code) msg.msg_id = AUDIO_MSG_DATA_REQUEST; msg.u.data = 0; - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&dev->lock, flags); ret = file_mq_send(&dev->mq, (FAR const char *) &msg, sizeof(msg), CONFIG_CXD56_MSG_PRIO); - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&dev->lock); if (ret != OK) { auderr("ERROR: file_mq_send to request failed (%d)\n", ret); } } - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&dev->lock, flags); } #else @@ -1365,19 +1365,19 @@ static void _process_audio(cxd56_dmahandle_t hdl, uint16_t err_code) /* Trigger new DMA job */ - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&dev->lock); if (dq_count(&dev->up_runq) > 0) { FAR struct ap_buffer_s *apb; apb = (struct ap_buffer_s *) dq_get(&dev->up_runq); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&dev->lock, flags); dev->dev.upper(dev->dev.priv, AUDIO_CALLBACK_DEQUEUE, apb, OK); - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&dev->lock); } - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&dev->lock, flags); if (err_code == CXD56_AUDIO_ECODE_DMA_TRANS) { @@ -3177,7 +3177,7 @@ static int cxd56_start_dma(FAR struct cxd56_dev_s *dev) uint32_t size; int ret = OK; - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&dev->lock); #ifdef CONFIG_AUDIO_CXD56_SRC FAR struct ap_buffer_s *src_apb; @@ -3190,9 +3190,9 @@ static int cxd56_start_dma(FAR struct cxd56_dev_s *dev) audwarn("Underrun \n"); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&dev->lock, flags); ret = cxd56_stop_dma(dev); - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&dev->lock); audwarn("STOP DMA due to underrun \n"); if (ret != CXD56_AUDIO_ECODE_OK) { @@ -3259,9 +3259,9 @@ static int cxd56_start_dma(FAR struct cxd56_dev_s *dev) { /* Turn on amplifier */ - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&dev->lock, flags); board_external_amp_mute_control(false); - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&dev->lock); /* Mask interrupts */ @@ -3377,10 +3377,10 @@ static int cxd56_start_dma(FAR struct cxd56_dev_s *dev) msg.msg_id = AUDIO_MSG_STOP; msg.u.data = 0; - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&dev->lock, flags); ret = file_mq_send(&dev->mq, (FAR const char *)&msg, sizeof(msg), CONFIG_CXD56_MSG_PRIO); - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&dev->lock); if (ret != OK) { @@ -3393,7 +3393,7 @@ static int cxd56_start_dma(FAR struct cxd56_dev_s *dev) } exit: - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&dev->lock, flags); return ret; } @@ -3422,12 +3422,12 @@ static int cxd56_enqueuebuffer(FAR struct audio_lowerhalf_s *lower, else { #endif - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&priv->lock); apb->dq_entry.flink = NULL; dq_put(&priv->up_pendq, &apb->dq_entry); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&priv->lock, flags); if (priv->mq.f_inode != NULL) { diff --git a/drivers/audio/cxd56.h b/drivers/audio/cxd56.h index 49d8f0e364..b4b1a7b857 100644 --- a/drivers/audio/cxd56.h +++ b/drivers/audio/cxd56.h @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef CONFIG_AUDIO @@ -298,6 +299,7 @@ struct cxd56_dev_s #endif bool reserved; /* True: Device is reserved */ volatile int result; /* The result of the last transfer */ + spinlock_t lock; /* Spinlock for SMP */ }; /****************************************************************************