Esempio n. 1
0
/* 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);
}
Esempio n. 2
0
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);
}