drivers: dma: sdma: Make access to DMA channel stats atomic

DMA channel stats like pending_length or free is not protected
and can be modified in parallel by a consumer and a producer.

This can result in non-atomic updates which in turn will result
in using stale data.

Fix this by making regions of code accessing dma stats atomic.

Fixes: e94c86f395 ("drivers: dma: Add initial support for NXP SDMA")
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
This commit is contained in:
Daniel Baluta 2025-05-26 15:34:15 +03:00 committed by Benjamin Cabé
commit 85b6ff0b0b

View file

@ -376,11 +376,14 @@ static int dma_nxp_sdma_get_status(const struct device *dev, uint32_t channel,
{
struct sdma_dev_data *dev_data = dev->data;
struct sdma_channel_data *chan_data;
unsigned int key;
chan_data = &dev_data->chan[channel];
key = irq_lock();
stat->free = chan_data->stat.free;
stat->pending_length = chan_data->stat.pending_length;
irq_unlock(key);
return 0;
}
@ -390,6 +393,7 @@ static int dma_nxp_sdma_reload(const struct device *dev, uint32_t channel, uint3
{
struct sdma_dev_data *dev_data = dev->data;
struct sdma_channel_data *chan_data;
unsigned int key;
chan_data = &dev_data->chan[channel];
@ -397,11 +401,13 @@ static int dma_nxp_sdma_reload(const struct device *dev, uint32_t channel, uint3
return 0;
}
key = irq_lock();
if (chan_data->direction == MEMORY_TO_PERIPHERAL) {
dma_nxp_sdma_produce(chan_data, size);
} else {
dma_nxp_sdma_consume(chan_data, size);
}
irq_unlock(key);
return 0;
}