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:
parent
312ff1c904
commit
85b6ff0b0b
1 changed files with 6 additions and 0 deletions
|
@ -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_dev_data *dev_data = dev->data;
|
||||||
struct sdma_channel_data *chan_data;
|
struct sdma_channel_data *chan_data;
|
||||||
|
unsigned int key;
|
||||||
|
|
||||||
chan_data = &dev_data->chan[channel];
|
chan_data = &dev_data->chan[channel];
|
||||||
|
|
||||||
|
key = irq_lock();
|
||||||
stat->free = chan_data->stat.free;
|
stat->free = chan_data->stat.free;
|
||||||
stat->pending_length = chan_data->stat.pending_length;
|
stat->pending_length = chan_data->stat.pending_length;
|
||||||
|
irq_unlock(key);
|
||||||
|
|
||||||
return 0;
|
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_dev_data *dev_data = dev->data;
|
||||||
struct sdma_channel_data *chan_data;
|
struct sdma_channel_data *chan_data;
|
||||||
|
unsigned int key;
|
||||||
|
|
||||||
chan_data = &dev_data->chan[channel];
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key = irq_lock();
|
||||||
if (chan_data->direction == MEMORY_TO_PERIPHERAL) {
|
if (chan_data->direction == MEMORY_TO_PERIPHERAL) {
|
||||||
dma_nxp_sdma_produce(chan_data, size);
|
dma_nxp_sdma_produce(chan_data, size);
|
||||||
} else {
|
} else {
|
||||||
dma_nxp_sdma_consume(chan_data, size);
|
dma_nxp_sdma_consume(chan_data, size);
|
||||||
}
|
}
|
||||||
|
irq_unlock(key);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue