diff --git a/arch/arm/src/sama5/sam_dmac.c b/arch/arm/src/sama5/sam_dmac.c index 33541943cc..9c0b3940ac 100644 --- a/arch/arm/src/sama5/sam_dmac.c +++ b/arch/arm/src/sama5/sam_dmac.c @@ -1470,7 +1470,7 @@ static void sam_freelinklist(struct sam_dmach_s *dmach) { struct sam_dmac_s *dmac = sam_controller(dmach); struct dma_linklist_s *desc; - struct dma_linklist_s *dscr; + uintptr_t paddr; /* Get the head of the link list and detach the link list from the DMA * channel @@ -1480,15 +1480,22 @@ static void sam_freelinklist(struct sam_dmach_s *dmach) dmach->llhead = NULL; dmach->lltail = NULL; - /* Reset each descriptor in the link list (thereby freeing them) */ - while (desc != NULL) { - dscr = (struct dma_linklist_s *)desc->dscr; + /* Get the physical address of the next desriptor in the list */ + + paddr = desc->dscr; + DEBUGASSERT(desc->saddr != 0); + + /* Free the descriptor by simply nullifying it */ + memset(desc, 0, sizeof(struct dma_linklist_s)); sam_givedsem(dmac); - desc = dscr; + + /* Get the virtual address of the next descriptor in the list */ + + desc = (struct dma_linklist_s *)sam_virtramaddr(paddr); } } @@ -1644,7 +1651,7 @@ static inline int sam_single(struct sam_dmach_s *dmach) sam_putdmac(dmac, DMAC_CHER_ENA(dmach->chan), SAM_DMAC_CHER_OFFSET); /* The DMA has been started. Once the transfer completes, hardware sets - * the interrupts and disables the channel. We will received buffer + * the interrupts and disables the channel. We will receive buffer * complete and transfer complete interrupts. * * Enable error, buffer complete and transfer complete interrupts.