From 09c1a3293b4aa7d60ff366ef084c33939e83117f Mon Sep 17 00:00:00 2001 From: Reto Schneider Date: Thu, 17 Oct 2024 00:16:39 +0200 Subject: [PATCH 1/2] drivers: dma: si32: Improve start and stop logic As per dma_stop() documentation, the implementation has to not just stop the transfer, but also to disable the channel. Before this commit, only the transfer has been stopped. Same goes for dma_start(). This also allows the enabling of a channel to be removed from dma_si32_config(). Signed-off-by: Reto Schneider --- drivers/dma/dma_si32.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/dma/dma_si32.c b/drivers/dma/dma_si32.c index 2e015af1370e0..f8dbea09ee7b5 100644 --- a/drivers/dma/dma_si32.c +++ b/drivers/dma/dma_si32.c @@ -333,8 +333,6 @@ static int dma_si32_config(const struct device *dev, uint32_t channel, struct dm return -EINVAL; } - SI32_DMACTRL_A_enable_channel(SI32_DMACTRL_0, channel); - return 0; } @@ -365,7 +363,6 @@ static int dma_si32_start(const struct device *dev, const uint32_t channel) __ASSERT(SI32_DMACTRL_A_is_primary_selected(SI32_DMACTRL_0, channel), "Primary descriptors must be used for basic and auto-request operations."); __ASSERT(SI32_SCONFIG_0->CONFIG.FDMAEN, "Fast mode is recommened to be enabled."); - __ASSERT(SI32_DMACTRL_0->CHENSET.U32 & BIT(channel), "Channel must be enabled."); __ASSERT(SI32_DMACTRL_0->CHSTATUS.U32 & BIT(channel), "Channel must be waiting for request"); @@ -377,6 +374,8 @@ static int dma_si32_start(const struct device *dev, const uint32_t channel) /* Enable interrupt for this DMA channels. */ irq_enable(DMACH0_IRQn + channel); + SI32_DMACTRL_A_enable_channel(SI32_DMACTRL_0, channel); + /* memory-to-memory transfers have to be started by this driver. When peripherals are * involved, the caller has to enable the peripheral to start the transfer. */ @@ -405,6 +404,8 @@ static int dma_si32_stop(const struct device *dev, const uint32_t channel) channel_descriptors[channel].CONFIG.TMD = 0; /* Stop the DMA channel. */ + SI32_DMACTRL_A_disable_channel(SI32_DMACTRL_0, channel); + return 0; } From 4c82250deb6b4c33c3252efc4b675ed979f65d0a Mon Sep 17 00:00:00 2001 From: Reto Schneider Date: Wed, 16 Oct 2024 23:43:58 +0200 Subject: [PATCH 2/2] drivers: dma: si32: Prevent configuration of in-use DMA channel As per Zephyr DMA documentation, dma_config() must not be done on a running channel. Signed-off-by: Reto Schneider --- drivers/dma/dma_si32.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/dma/dma_si32.c b/drivers/dma/dma_si32.c index f8dbea09ee7b5..f6b8a46f1177c 100644 --- a/drivers/dma/dma_si32.c +++ b/drivers/dma/dma_si32.c @@ -141,6 +141,14 @@ static int dma_si32_config(const struct device *dev, uint32_t channel, struct dm return -EINVAL; } + /* Prevent messing up (potentially) ongoing DMA operations and their settings. This behavior + * is required by the Zephyr DMA API. + */ + if (SI32_DMACTRL_A_is_channel_enabled(SI32_DMACTRL_0, channel)) { + LOG_ERR("DMA channel is currently in use"); + return -EBUSY; + } + channel_descriptor = &channel_descriptors[channel]; if (cfg == NULL) {