diff --git a/arch/arm/src/stm32h7/stm32_dma.c b/arch/arm/src/stm32h7/stm32_dma.c index 922096e848f..a5379024af4 100644 --- a/arch/arm/src/stm32h7/stm32_dma.c +++ b/arch/arm/src/stm32h7/stm32_dma.c @@ -159,6 +159,10 @@ struct stm32_dma_ops_s void (*dma_setup)(DMA_HANDLE handle, stm32_dmacfg_t *cfg); + /* Free the DMA */ + + void (*dma_free)(DMA_HANDLE handle); + /* Start the DMA */ void (*dma_start)(DMA_HANDLE handle, dma_callback_t callback, @@ -185,6 +189,7 @@ struct stm32_dma_ops_s static void stm32_mdma_disable(DMA_CHANNEL dmachan); static int stm32_mdma_interrupt(int irq, void *context, void *arg); static void stm32_mdma_setup(DMA_HANDLE handle, stm32_dmacfg_t *cfg); +static void stm32_mdma_free(DMA_HANDLE handle); static void stm32_mdma_start(DMA_HANDLE handle, dma_callback_t callback, void *arg, bool half); static size_t stm32_mdma_residual(DMA_HANDLE handle); @@ -200,6 +205,7 @@ static void stm32_mdma_dump(DMA_HANDLE handle, const char *msg); static void stm32_sdma_disable(DMA_CHANNEL dmachan); static int stm32_sdma_interrupt(int irq, void *context, void *arg); static void stm32_sdma_setup(DMA_HANDLE handle, stm32_dmacfg_t *cfg); +static void stm32_sdma_free(DMA_HANDLE handle); static void stm32_sdma_start(DMA_HANDLE handle, dma_callback_t callback, void *arg, bool half); static size_t stm32_sdma_residual(DMA_HANDLE handle); @@ -215,6 +221,7 @@ static void stm32_sdma_dump(DMA_HANDLE handle, const char *msg); static void stm32_bdma_disable(DMA_CHANNEL dmachan); static int stm32_bdma_interrupt(int irq, void *context, void *arg); static void stm32_bdma_setup(DMA_HANDLE handle, stm32_dmacfg_t *cfg); +static void stm32_bdma_free(DMA_HANDLE handle); static void stm32_bdma_start(DMA_HANDLE handle, dma_callback_t callback, void *arg, bool half); static size_t stm32_bdma_residual(DMA_HANDLE handle); @@ -265,6 +272,7 @@ struct stm32_dma_ops_s g_dma_ops[DMA_CONTROLLERS] = .dma_disable = stm32_mdma_disable, .dma_interrupt = stm32_mdma_interrupt, .dma_setup = stm32_mdma_setup, + .dma_free = stm32_mdma_free, .dma_start = stm32_mdma_start, .dma_residual = stm32_mdma_residual, #ifdef CONFIG_STM32H7_DMACAPABLE @@ -287,6 +295,7 @@ struct stm32_dma_ops_s g_dma_ops[DMA_CONTROLLERS] = .dma_disable = stm32_sdma_disable, .dma_interrupt = stm32_sdma_interrupt, .dma_setup = stm32_sdma_setup, + .dma_free = stm32_sdma_free, .dma_start = stm32_sdma_start, .dma_residual = stm32_sdma_residual, #ifdef CONFIG_STM32H7_DMACAPABLE @@ -309,6 +318,7 @@ struct stm32_dma_ops_s g_dma_ops[DMA_CONTROLLERS] = .dma_disable = stm32_sdma_disable, .dma_interrupt = stm32_sdma_interrupt, .dma_setup = stm32_sdma_setup, + .dma_free = stm32_sdma_free, .dma_start = stm32_sdma_start, .dma_residual = stm32_sdma_residual, #ifdef CONFIG_STM32H7_DMACAPABLE @@ -331,6 +341,7 @@ struct stm32_dma_ops_s g_dma_ops[DMA_CONTROLLERS] = .dma_disable = stm32_bdma_disable, .dma_interrupt = stm32_bdma_interrupt, .dma_setup = stm32_bdma_setup, + .dma_free = stm32_bdma_free, .dma_start = stm32_bdma_start, .dma_residual = stm32_bdma_residual, #ifdef CONFIG_STM32H7_DMACAPABLE @@ -959,6 +970,21 @@ static void stm32_mdma_setup(DMA_HANDLE handle, stm32_dmacfg_t *cfg) #warning stm32_mdma_setup not implemented } +/**************************************************************************** + * Name: stm32_mdma_free + * + * Description: + * Free master DMA + * + ****************************************************************************/ + +static void stm32_mdma_free(DMA_HANDLE handle) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + + dmachan_putreg(dmachan, STM32_BDMACH_CNDTR_OFFSET, 0); +} + /**************************************************************************** * Name: stm32_mdma_start * @@ -1393,6 +1419,21 @@ static void stm32_sdma_setup(DMA_HANDLE handle, stm32_dmacfg_t *cfg) dmachan_putreg(dmachan, STM32_DMA_SCR_OFFSET, regval); } +/**************************************************************************** + * Name: stm32_sdma_sfree + * + * Description: + * Free master DMA + * + ****************************************************************************/ + +static void stm32_sdma_free(DMA_HANDLE handle) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + + dmachan_putreg(dmachan, STM32_DMA_SNDTR_OFFSET, 0); +} + /**************************************************************************** * Name: stm32_sdma_start * @@ -1961,6 +2002,21 @@ static void stm32_bdma_setup(DMA_HANDLE handle, stm32_dmacfg_t *cfg) dmachan_putreg(dmachan, STM32_BDMACH_CCR_OFFSET, regval); } +/**************************************************************************** + * Name: stm32_bdma_sfree + * + * Description: + * Free master DMA + * + ****************************************************************************/ + +static void stm32_bdma_free(DMA_HANDLE handle) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + + dmachan_putreg(dmachan, STM32_BDMACH_CNDTR_OFFSET, 0); +} + /**************************************************************************** * Name: stm32_bdma_start * @@ -2471,6 +2527,10 @@ void stm32_dmafree(DMA_HANDLE handle) controller = dmachan->ctrl; DEBUGASSERT(controller >= MDMA && controller <= BDMA); + /* Do controller specific free */ + + g_dma_ops[controller].dma_free(handle); + /* Get DMAMUX associated with DMA controller */ dmamux = g_dma[controller].dmamux; diff --git a/arch/arm/src/stm32h7/stm32_serial.c b/arch/arm/src/stm32h7/stm32_serial.c index 2758273fcc6..e73dbd599cc 100644 --- a/arch/arm/src/stm32h7/stm32_serial.c +++ b/arch/arm/src/stm32h7/stm32_serial.c @@ -2382,6 +2382,9 @@ static void up_dma_shutdown(struct uart_dev_s *dev) stm32_dmafree(priv->txdma); priv->txdma = NULL; + + dev->dmatx.length = 0; + dev->dmatx.nlength = 0; } #endif }