Beispiel #1
0
void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma)
{
	unsigned long flags;
	int sgslot;
	struct sgdma_state *sg_state;
	u32 csr = CAMDMA_CSR_TRANS_ERR;

	
	omap24xxcam_dma_stop(&sgdma->dma, csr);

	spin_lock_irqsave(&sgdma->lock, flags);

	if (sgdma->free_sgdma < NUM_SG_DMA) {
		sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA;
		sg_state = sgdma->sg_state + sgslot;
		if (sg_state->next_sglist != 0) {
			
			sgdma_callback_t callback = sg_state->callback;
			void *arg = sg_state->arg;
			sgdma->free_sgdma++;
			if (callback) {
				
				spin_unlock(&sgdma->lock);
				(*callback) (sgdma, csr, arg);
				spin_lock(&sgdma->lock);
			}
		}
	}

	spin_unlock_irqrestore(&sgdma->lock, flags);
}
/* Sync scatter-gather DMA by aborting any DMA transfers currently in progress.
 * Any queued scatter-gather DMA transactions that have not yet been started
 * will remain queued.  The DMA controller will be idle after this routine
 * completes.  When the scatter-gather queue is restarted, the next
 * scatter-gather DMA transfer will begin at the start of a new transaction.
 */
void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma)
{
	unsigned long flags;
	int sgslot;
	struct sgdma_state *sg_state;
	u32 csr = CAMDMA_CSR_TRANS_ERR;

	/* stop any DMA transfers in progress */
	omap24xxcam_dma_stop(&sgdma->dma, csr);

	spin_lock_irqsave(&sgdma->lock, flags);

	if (sgdma->free_sgdma < NUM_SG_DMA) {
		sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA;
		sg_state = sgdma->sg_state + sgslot;
		if (sg_state->next_sglist != 0) {
			/* This DMA transfer was in progress, so abort it. */
			sgdma_callback_t callback = sg_state->callback;
			void *arg = sg_state->arg;
			sgdma->free_sgdma++;
			if (callback) {
				/* leave interrupts masked */
				spin_unlock(&sgdma->lock);
				(*callback) (sgdma, csr, arg);
				spin_lock(&sgdma->lock);
			}
		}
	}

	spin_unlock_irqrestore(&sgdma->lock, flags);
}
Beispiel #3
0
/* Camera DMA interrupt service routine. */
void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma)
{
	int dmach;
	dma_callback_t callback;
	void *arg;
	u32 csr;
	const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
		| CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
		| CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;

	spin_lock(&dma->lock);

	if (dma->free_dmach == NUM_CAMDMA_CHANNELS) {
		/* A camera DMA interrupt occurred while all channels
		 * are idle, so we'll acknowledge the interrupt in the
		 * IRQSTATUS register and exit.
		 */
		omap24xxcam_dmahw_ack_all(dma->base);
		spin_unlock(&dma->lock);
		return;
	}

	while (dma->free_dmach < NUM_CAMDMA_CHANNELS) {
		dmach = (dma->next_dmach + dma->free_dmach)
			% NUM_CAMDMA_CHANNELS;
		if (omap24xxcam_dmahw_running(dma->base, dmach)) {
			/* This buffer hasn't finished yet, so we're done. */
			break;
		}
		csr = omap24xxcam_dmahw_ack_ch(dma->base, dmach);
		if (csr & csr_error) {
			/* A DMA error occurred, so stop all DMA
			 * transfers in progress.
			 */
			spin_unlock(&dma->lock);
			omap24xxcam_dma_stop(dma, csr);
			return;
		} else {
			callback = dma->ch_state[dmach].callback;
			arg = dma->ch_state[dmach].arg;
			dma->free_dmach++;
			if (callback) {
				spin_unlock(&dma->lock);
				(*callback) (dma, csr, arg);
				spin_lock(&dma->lock);
			}
		}
	}

	spin_unlock(&dma->lock);

	omap24xxcam_sgdma_process(
		container_of(dma, struct omap24xxcam_sgdma, dma));
}
Beispiel #4
0
void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma)
{
	int dmach;
	dma_callback_t callback;
	void *arg;
	u32 csr;
	const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
		| CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
		| CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;

	spin_lock(&dma->lock);

	if (dma->free_dmach == NUM_CAMDMA_CHANNELS) {
		
		omap24xxcam_dmahw_ack_all(dma->base);
		spin_unlock(&dma->lock);
		return;
	}

	while (dma->free_dmach < NUM_CAMDMA_CHANNELS) {
		dmach = (dma->next_dmach + dma->free_dmach)
			% NUM_CAMDMA_CHANNELS;
		if (omap24xxcam_dmahw_running(dma->base, dmach)) {
			
			break;
		}
		csr = omap24xxcam_dmahw_ack_ch(dma->base, dmach);
		if (csr & csr_error) {
			
			spin_unlock(&dma->lock);
			omap24xxcam_dma_stop(dma, csr);
			return;
		} else {
			callback = dma->ch_state[dmach].callback;
			arg = dma->ch_state[dmach].arg;
			dma->free_dmach++;
			if (callback) {
				spin_unlock(&dma->lock);
				(*callback) (dma, csr, arg);
				spin_lock(&dma->lock);
			}
		}
	}

	spin_unlock(&dma->lock);

	omap24xxcam_sgdma_process(
		container_of(dma, struct omap24xxcam_sgdma, dma));
}
Beispiel #5
0
/* Sync scatter-gather DMA by aborting any DMA transfers currently in progress.
 * Any queued scatter-gather DMA transactions that have not yet been started
 * will remain queued.  The DMA controller will be idle after this routine
 * completes.  When the scatter-gather queue is restarted, the next
 * scatter-gather DMA transfer will begin at the start of a new transaction.
 */
void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma)
{
	unsigned long flags;
	int sgslot;
	struct sgdma_state *sg_state;
	u32 csr = CAMDMA_CSR_TRANS_ERR;

	/* stop any DMA transfers in progress */
	omap24xxcam_dma_stop(&sgdma->dma, csr);

	spin_lock_irqsave(&sgdma->lock, flags);

	if (sgdma->free_sgdma < NUM_SG_DMA) {
		sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA;
		sg_state = sgdma->sg_state + sgslot;
		if (sg_state->next_sglist != 0) {
			/* This DMA transfer was in progress, so abort it. */
			sgdma_callback_t callback = sg_sta