rp2/rp2_dma: Disable DMA IRQ before clearing handler function.

Both the overall IRQ line and the per-channel IRQ, for good measure.

Otherwise, soft reset will remove the handler before the finaliser for the
DMA object(s) run and trigger IRQs if the channel is still active.

Closes #18765

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
This commit is contained in:
Angus Gratton
2026-03-12 10:50:19 +11:00
committed by Damien George
parent 06dbc1f486
commit d2cda57e9d

View File

@@ -427,6 +427,9 @@ static mp_obj_t rp2_dma_close(mp_obj_t self_in) {
uint8_t channel = self->channel;
if (channel != CHANNEL_CLOSED) {
// Disable channel IRQ
dma_channel_set_irq0_enabled(channel, false);
// Reset this channel's registers to their default values (zeros).
dma_channel_config config = { .ctrl = 0 };
dma_channel_configure(channel, &config, NULL, NULL, 0, false);
@@ -441,7 +444,6 @@ static mp_obj_t rp2_dma_close(mp_obj_t self_in) {
if (irq) {
irq->parent = MP_OBJ_NULL;
irq->handler = MP_OBJ_NULL;
dma_channel_set_irq0_enabled(channel, false);
}
dma_channel_unclaim(channel);
self->channel = CHANNEL_CLOSED;
@@ -479,7 +481,8 @@ void rp2_dma_init(void) {
}
void rp2_dma_deinit(void) {
// Remove our interrupt handler.
// Disable and remove our interrupt handler.
irq_set_enabled(DMA_IRQ_0, false);
irq_remove_handler(DMA_IRQ_0, rp2_dma_irq_handler);
}