From 7f0643de6d3a97a9c907f9c667843b68eaebf654 Mon Sep 17 00:00:00 2001 From: David Sidrane Date: Tue, 5 Dec 2023 04:07:53 -0800 Subject: [PATCH] s32k3xx:edma clear state before callback add idle check This prevents dma stop operations called of a completion call back from rentering, the callback and ensures that the call back will see the idle state. --- arch/arm/src/s32k3xx/s32k3xx_edma.c | 33 ++++++++++++++++++++++++----- arch/arm/src/s32k3xx/s32k3xx_edma.h | 16 +++++++++++++- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/arch/arm/src/s32k3xx/s32k3xx_edma.c b/arch/arm/src/s32k3xx/s32k3xx_edma.c index 053c52c7ca..b0e193b925 100644 --- a/arch/arm/src/s32k3xx/s32k3xx_edma.c +++ b/arch/arm/src/s32k3xx/s32k3xx_edma.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/s32k3xx/s32k3xx_edma.c * - * Copyright (C) 2019, 2021 Gregory Nutt. All rights reserved. + * Copyright (C) 2019, 2021, 2023 Gregory Nutt. All rights reserved. * Copyright 2022 NXP * Authors: Gregory Nutt * David Sidrane @@ -708,6 +708,8 @@ static void s32k3xx_dmaterminate(struct s32k3xx_dmach_s *dmach, int result) struct s32k3xx_edmatcd_s *next; #endif uint8_t chan; + edma_callback_t callback; + void *arg; chan = dmach->chan; @@ -749,14 +751,17 @@ static void s32k3xx_dmaterminate(struct s32k3xx_dmach_s *dmach, int result) /* Perform the DMA complete callback */ - if (dmach->callback) - { - dmach->callback((DMACH_HANDLE)dmach, dmach->arg, true, result); - } + callback = dmach->callback; + arg = dmach->arg; dmach->callback = NULL; dmach->arg = NULL; dmach->state = S32K3XX_DMA_IDLE; + + if (callback) + { + callback((DMACH_HANDLE)dmach, arg, true, result); + } } /**************************************************************************** @@ -1495,6 +1500,24 @@ unsigned int s32k3xx_dmach_getcount(DMACH_HANDLE *handle) return remaining; } +/**************************************************************************** + * Name: s32k3xx_dmach_idle + * + * Description: + * This function checks if the dma is idle + * + * Returned Value: + * 0 - if idle + * !0 - not + * + ****************************************************************************/ + +unsigned int s32k3xx_dmach_idle(DMACH_HANDLE handle) +{ + struct s32k3xx_dmach_s *dmach = (struct s32k3xx_dmach_s *)handle; + return dmach->state == S32K3XX_DMA_IDLE ? 0 : -1; +} + /**************************************************************************** * Name: s32k3xx_dmasample * diff --git a/arch/arm/src/s32k3xx/s32k3xx_edma.h b/arch/arm/src/s32k3xx/s32k3xx_edma.h index 5c0441ac77..00fff86f9c 100644 --- a/arch/arm/src/s32k3xx/s32k3xx_edma.h +++ b/arch/arm/src/s32k3xx/s32k3xx_edma.h @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/s32k3xx/s32k3xx_edma.h * - * Copyright (C) 2019, 2021 Gregory Nutt. All rights reserved. + * Copyright (C) 2019, 2021, 2023 Gregory Nutt. All rights reserved. * Copyright 2022 NXP * Authors: Gregory Nutt * David Sidrane @@ -431,6 +431,20 @@ void s32k3xx_dmach_stop(DMACH_HANDLE handle); unsigned int s32k3xx_dmach_getcount(DMACH_HANDLE *handle); +/**************************************************************************** + * Name: s32k3xx_dmach_idle + * + * Description: + * This function checks if the dma is idle + * + * Returned Value: + * 0 - if idle + * !0 - not + * + ****************************************************************************/ + +unsigned int s32k3xx_dmach_idle(DMACH_HANDLE handle); + /**************************************************************************** * Name: s32k3xx_dmasample *