/* Abort all chained DMA transfers. After all transfers have been * aborted and the DMA controller is idle, the completion routines for * any aborted transfers will be called in sequence. The DMA * controller may not be idle after this routine completes, because * the completion routines might start new transfers. */ static void omap24xxcam_dma_abort(struct omap24xxcam_dma *dma, u32 csr) { unsigned long flags; int dmach, i, free_dmach; dma_callback_t callback; void *arg; spin_lock_irqsave(&dma->lock, flags); /* stop any DMA transfers in progress */ dmach = (dma->next_dmach + dma->free_dmach) % NUM_CAMDMA_CHANNELS; for (i = 0; i < NUM_CAMDMA_CHANNELS; i++) { omap24xxcam_dmahw_abort_ch(dma->base, dmach); dmach = (dmach + 1) % NUM_CAMDMA_CHANNELS; } /* We have to be careful here because the callback routine * might start a new DMA transfer, and we only want to abort * transfers that were started before this routine was called. */ free_dmach = dma->free_dmach; while ((dma->free_dmach < NUM_CAMDMA_CHANNELS) && (free_dmach < NUM_CAMDMA_CHANNELS)) { dmach = (dma->next_dmach + dma->free_dmach) % NUM_CAMDMA_CHANNELS; callback = dma->ch_state[dmach].callback; arg = dma->ch_state[dmach].arg; dma->free_dmach++; free_dmach++; if (callback) { /* leave interrupts disabled during callback */ spin_unlock(&dma->lock); (*callback) (dma, csr, arg); spin_lock(&dma->lock); } } spin_unlock_irqrestore(&dma->lock, flags); }
static void omap24xxcam_dma_abort(struct omap24xxcam_dma *dma, u32 csr) { unsigned long flags; int dmach, i, free_dmach; dma_callback_t callback; void *arg; spin_lock_irqsave(&dma->lock, flags); dmach = (dma->next_dmach + dma->free_dmach) % NUM_CAMDMA_CHANNELS; for (i = 0; i < NUM_CAMDMA_CHANNELS; i++) { omap24xxcam_dmahw_abort_ch(dma->base, dmach); dmach = (dmach + 1) % NUM_CAMDMA_CHANNELS; } free_dmach = dma->free_dmach; while ((dma->free_dmach < NUM_CAMDMA_CHANNELS) && (free_dmach < NUM_CAMDMA_CHANNELS)) { dmach = (dma->next_dmach + dma->free_dmach) % NUM_CAMDMA_CHANNELS; callback = dma->ch_state[dmach].callback; arg = dma->ch_state[dmach].arg; dma->free_dmach++; free_dmach++; if (callback) { spin_unlock(&dma->lock); (*callback) (dma, csr, arg); spin_lock(&dma->lock); } } spin_unlock_irqrestore(&dma->lock, flags); }