@@ -350,13 +350,15 @@ static void buffer_queue(struct vb2_buffer *vb)
dbg("active_buf_cnt: %d", fimc->vid_cap.active_buf_cnt);
- if (vid_cap->active_buf_cnt >= vid_cap->reqbufs_count ||
- vid_cap->active_buf_cnt >= FIMC_MAX_OUT_BUFS) {
- if (!test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) {
+ if (vid_cap->active_buf_cnt == FIMC_MAX_OUT_BUFS)
+ set_bit(ST_CAPT_STREAM, &fimc->state);
+
+ if (test_bit(ST_CAPT_LAST_IRQ, &fimc->state) ||
+ !test_bit(ST_CAPT_RUN, &fimc->state)) {
fimc_activate_capture(ctx);
- dbg("");
- }
+ clear_bit(ST_CAPT_LAST_IRQ, &fimc->state);
}
+
spin_unlock_irqrestore(&fimc->slock, flags);
}
@@ -334,9 +334,14 @@ static void fimc_capture_handler(struct fimc_dev *fimc)
if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
cap->buf_index = 0;
- } else if (test_and_clear_bit(ST_CAPT_STREAM, &fimc->state) &&
- cap->active_buf_cnt <= 1) {
- fimc_deactivate_capture(fimc);
+ } else {
+ clear_bit(ST_CAPT_STREAM, &fimc->state);
+ }
+
+ if (cap->active_buf_cnt == 0) {
+ clear_bit(ST_CAPT_RUN, &fimc->state);
+ if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
+ cap->buf_index = 0;
}
dbg("frame: %d, active_buf_cnt= %d",
@@ -346,6 +351,7 @@ static void fimc_capture_handler(struct fimc_dev *fimc)
static irqreturn_t fimc_isr(int irq, void *priv)
{
struct fimc_dev *fimc = priv;
+ struct fimc_vid_cap *cap = &fimc->vid_cap;
BUG_ON(!fimc);
fimc_hw_clear_irq(fimc);
@@ -372,10 +378,12 @@ static irqreturn_t fimc_isr(int irq, void *priv)
if (test_bit(ST_CAPT_RUN, &fimc->state))
fimc_capture_handler(fimc);
-
- if (test_and_clear_bit(ST_CAPT_PEND, &fimc->state)) {
+ else if (test_bit(ST_CAPT_PEND, &fimc->state))
set_bit(ST_CAPT_RUN, &fimc->state);
- wake_up(&fimc->irq_queue);
+
+ if (cap->active_buf_cnt == 1) {
+ fimc_deactivate_capture(fimc);
+ set_bit(ST_CAPT_LAST_IRQ, &fimc->state);
}
isr_unlock:
@@ -56,6 +56,7 @@ enum fimc_dev_flags {
ST_CAPT_RUN,
ST_CAPT_STREAM,
ST_CAPT_SHUT,
+ ST_CAPT_LAST_IRQ,
};
#define fimc_m2m_active(dev) test_bit(ST_OUTDMA_RUN, &(dev)->state)