From 9eaed805c151c41a896168b52eb83c735f08d028 Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Mon, 16 Dec 2024 11:59:49 -0800 Subject: [PATCH] drivers: audio: dmic_mcux: init active_buf_idx when setting up dma In case the dmic had previous been run and stopped, make sure active_buf_idx is initialized to 0 when setting up dma on start, otherwise the dma callback can return the wrong buffer. Also purge the rx_queue before freeing the slab buffers, to minimize risk of any async read request getting back a slab buffer that is freed. Signed-off-by: Mike J. Chen --- drivers/audio/dmic_mcux.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/audio/dmic_mcux.c b/drivers/audio/dmic_mcux.c index 0f032e8368c..ec2b9f0eecd 100644 --- a/drivers/audio/dmic_mcux.c +++ b/drivers/audio/dmic_mcux.c @@ -125,6 +125,8 @@ static int dmic_mcux_enable_dma(struct mcux_dmic_drv_data *drv_data, bool enable } } else { if (dma_stop(pdm_channel->dma, pdm_channel->dma_chan)) { + LOG_ERR("Error stopping DMA for HW channel %d", + hw_chan); ret = -EIO; } } @@ -181,14 +183,17 @@ static int dmic_mcux_stop(struct mcux_dmic_drv_data *drv_data) /* Disable DMA */ dmic_mcux_enable_dma(drv_data, false); + /* Purge the RX queue first, to minimize possibility of + * an async read request returning a ptr to a buffer we're + * about to free. + */ + k_msgq_purge(drv_data->rx_queue); + /* Free all memory slabs */ for (uint32_t i = 0; i < CONFIG_DMIC_MCUX_DMA_BUFFERS; i++) { k_mem_slab_free(drv_data->mem_slab, drv_data->dma_bufs[i]); } - /* Purge the RX queue as well. */ - k_msgq_purge(drv_data->rx_queue); - drv_data->dmic_state = DMIC_STATE_CONFIGURED; return 0; @@ -283,6 +288,7 @@ static int dmic_mcux_setup_dma(const struct device *dev) uint8_t hw_chan; int ret = 0; + drv_data->active_buf_idx = 0; /* Setup DMA configuration common between all channels */ dma_cfg.user_data = drv_data;