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 void stop_streaming(struct vb2_queue *q) { struct fimc_ctx *ctx = q->drv_priv; fimc_m2m_shutdown(ctx); fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); pm_runtime_put(&ctx->fimc_dev->pdev->dev); }
static int stop_streaming(struct vb2_queue *q) { struct fimc_ctx *ctx = q->drv_priv; int ret; ret = fimc_m2m_shutdown(ctx); if (ret == -ETIMEDOUT) fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); pm_runtime_put(&ctx->fimc_dev->pdev->dev); return 0; }
/* Complete the transaction which has been scheduled for execution. */ static void fimc_m2m_shutdown(struct fimc_ctx *ctx) { struct fimc_dev *fimc = ctx->fimc_dev; int ret; if (!fimc_m2m_pending(fimc)) return; fimc_ctx_state_lock_set(FIMC_CTX_SHUT, ctx); ret = wait_event_timeout(fimc->irq_queue, !fimc_ctx_state_is_set(FIMC_CTX_SHUT, ctx), FIMC_SHUTDOWN_TIMEOUT); /* * In case of a timeout the buffers are not released in the interrupt * handler so return them here with the error flag set, if there are * any on the queue. */ if (ret == 0) fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); }
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; }