/* 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)); }
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)); }