static irqreturn_t fimc_irq_handler(int irq, void *priv) { struct fimc_dev *fimc = priv; struct fimc_ctx *ctx; fimc_hw_clear_irq(fimc); spin_lock(&fimc->slock); if (test_and_clear_bit(ST_M2M_PEND, &fimc->state)) { if (test_and_clear_bit(ST_M2M_SUSPENDING, &fimc->state)) { set_bit(ST_M2M_SUSPENDED, &fimc->state); wake_up(&fimc->irq_queue); goto out; } ctx = v4l2_m2m_get_curr_priv(fimc->m2m.m2m_dev); if (ctx != NULL) { spin_unlock(&fimc->slock); fimc_m2m_job_finish(ctx, VB2_BUF_STATE_DONE); if (ctx->state & FIMC_CTX_SHUT) { ctx->state &= ~FIMC_CTX_SHUT; wake_up(&fimc->irq_queue); } return IRQ_HANDLED; } } else if (test_bit(ST_CAPT_PEND, &fimc->state)) { int last_buf = test_bit(ST_CAPT_JPEG, &fimc->state) && fimc->vid_cap.reqbufs_count == 1; fimc_capture_irq_handler(fimc, !last_buf); } out: spin_unlock(&fimc->slock); return IRQ_HANDLED; }
static irqreturn_t fimc_isr(int irq, void *priv) { struct fimc_dev *fimc = priv; struct fimc_vid_cap *cap = &fimc->vid_cap; struct fimc_ctx *ctx; fimc_hw_clear_irq(fimc); if (test_and_clear_bit(ST_M2M_PEND, &fimc->state)) { ctx = v4l2_m2m_get_curr_priv(fimc->m2m.m2m_dev); if (ctx != NULL) { fimc_m2m_job_finish(ctx, VB2_BUF_STATE_DONE); spin_lock(&ctx->slock); if (ctx->state & FIMC_CTX_SHUT) { ctx->state &= ~FIMC_CTX_SHUT; wake_up(&fimc->irq_queue); } spin_unlock(&ctx->slock); } return IRQ_HANDLED; } spin_lock(&fimc->slock); if (test_bit(ST_CAPT_PEND, &fimc->state)) { fimc_capture_irq_handler(fimc); if (cap->active_buf_cnt == 1) { fimc_deactivate_capture(fimc); clear_bit(ST_CAPT_STREAM, &fimc->state); } } spin_unlock(&fimc->slock); return IRQ_HANDLED; }