Exemplo n.º 1
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));
}
Exemplo n.º 2
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));
}