From patchwork Wed Dec 29 00:30:28 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sungchun Kang X-Patchwork-Id: 437641 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oBT0sCnp018861 for ; Wed, 29 Dec 2010 00:54:12 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752828Ab0L2AyH (ORCPT ); Tue, 28 Dec 2010 19:54:07 -0500 Received: from ganesha.gnumonks.org ([213.95.27.120]:43249 "EHLO ganesha.gnumonks.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751993Ab0L2AyG (ORCPT ); Tue, 28 Dec 2010 19:54:06 -0500 Received: from uucp by ganesha.gnumonks.org with local-bsmtp (Exim 4.69) (envelope-from ) id 1PXkIk-0003Pl-NI; Wed, 29 Dec 2010 01:54:02 +0100 Received: from [12.23.102.184] (helo=localhost.localdomain) by jackpot.kr.gnumonks.org with esmtp (Exim 4.69) (envelope-from ) id 1PXjE9-0000m0-2J; Wed, 29 Dec 2010 08:45:13 +0900 From: Sungchun Kang To: linux-media@vger.kernel.org, linux-samsung-soc@vger.kernel.org Cc: s.nawrocki@samsung.com, kgene.kim@samsung.com, Sungchun Kang Subject: [PATCH] [media]: s5p-fimc: fix ISR and buffer handling for fimc-capture Date: Wed, 29 Dec 2010 09:30:28 +0900 Message-Id: <1293582628-15547-1-git-send-email-sungchun.kang@samsung.com> X-Mailer: git-send-email 1.6.2.5 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 29 Dec 2010 00:54:12 +0000 (UTC) diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 4e4441f..0a3b344 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -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); } diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 2374fd8..4a85966 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -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: diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index 1f1beaa..58cb2e0 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h @@ -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)