dma: Repeated start/stop support for gpdma
Allows for repeatedly calling start/stop on designwares gpdma.
@@ -417,6 +417,13 @@ out:
return ret;
}
+bool dw_dma_is_enabled(const struct device *dev, uint32_t channel)
+{
+ const struct dw_dma_dev_cfg *const dev_cfg = dev->config;
+
+ return dw_read(dev_cfg->base, DW_DMA_CHAN_EN) & DW_CHAN_MASK(channel);
+}
+
int dw_dma_start(const struct device *dev, uint32_t channel)
{
const struct dw_dma_dev_cfg *const dev_cfg = dev->config;
@@ -429,6 +436,10 @@ int dw_dma_start(const struct device *dev, uint32_t channel)
goto out;
}
+ if (dw_dma_is_enabled(dev, channel)) {
+ goto out;
+ }
+
struct dw_dma_chan_data *chan_data = &dev_data->chan[channel];
/* validate channel state */
@@ -513,6 +524,10 @@ int dw_dma_stop(const struct device *dev, uint32_t channel)
goto out;
}
+ if (!dw_dma_is_enabled(dev, channel)) {
+ goto out;
+ }
+
#if defined(CONFIG_DMA_DW_HW_LLI) || defined(CONFIG_DMA_DW_SUSPEND_DRAIN)
struct dw_dma_chan_data *chan_data = &dev_data->chan[channel];
#endif
