diff options
author | Hyunwoong Kim <khw0178.kim@samsung.com> | 2010-12-29 02:47:49 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-21 19:31:40 -0400 |
commit | 65777e5c58bd3b25fcba39eddb98d8a8ce35d3be (patch) | |
tree | cb074d62daa7d028364489b3c303c72851a4728b /drivers | |
parent | 1b09f292eb99fd6a3601e8421c463905dbb0a866 (diff) |
[media] s5p-fimc: Support stop_streaming and job_abort
This patch adds callback functions, stop_streaming and job_abort,
to abort or finish any DMA in progress. stop_streaming is called
by videobuf2 framework and job_abort is called by m2m framework.
ST_M2M_PEND state is added to discard the next job.
Reviewed-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Hyunwoong Kim <khw0178.kim@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.c | 35 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.h | 1 |
2 files changed, 34 insertions, 2 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 560cd21dae28..cd8a3003f1aa 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
@@ -307,6 +307,23 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx) | |||
307 | return 0; | 307 | return 0; |
308 | } | 308 | } |
309 | 309 | ||
310 | static int stop_streaming(struct vb2_queue *q) | ||
311 | { | ||
312 | struct fimc_ctx *ctx = q->drv_priv; | ||
313 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
314 | |||
315 | if (!fimc_m2m_pending(fimc)) | ||
316 | return 0; | ||
317 | |||
318 | set_bit(ST_M2M_SHUT, &fimc->state); | ||
319 | |||
320 | wait_event_timeout(fimc->irq_queue, | ||
321 | !test_bit(ST_M2M_SHUT, &fimc->state), | ||
322 | FIMC_SHUTDOWN_TIMEOUT); | ||
323 | |||
324 | return 0; | ||
325 | } | ||
326 | |||
310 | static void fimc_capture_handler(struct fimc_dev *fimc) | 327 | static void fimc_capture_handler(struct fimc_dev *fimc) |
311 | { | 328 | { |
312 | struct fimc_vid_cap *cap = &fimc->vid_cap; | 329 | struct fimc_vid_cap *cap = &fimc->vid_cap; |
@@ -358,7 +375,10 @@ static irqreturn_t fimc_isr(int irq, void *priv) | |||
358 | 375 | ||
359 | spin_lock(&fimc->slock); | 376 | spin_lock(&fimc->slock); |
360 | 377 | ||
361 | if (test_and_clear_bit(ST_M2M_PEND, &fimc->state)) { | 378 | if (test_and_clear_bit(ST_M2M_SHUT, &fimc->state)) { |
379 | wake_up(&fimc->irq_queue); | ||
380 | goto isr_unlock; | ||
381 | } else if (test_and_clear_bit(ST_M2M_PEND, &fimc->state)) { | ||
362 | struct vb2_buffer *src_vb, *dst_vb; | 382 | struct vb2_buffer *src_vb, *dst_vb; |
363 | struct fimc_ctx *ctx = v4l2_m2m_get_curr_priv(fimc->m2m.m2m_dev); | 383 | struct fimc_ctx *ctx = v4l2_m2m_get_curr_priv(fimc->m2m.m2m_dev); |
364 | 384 | ||
@@ -634,7 +654,17 @@ dma_unlock: | |||
634 | 654 | ||
635 | static void fimc_job_abort(void *priv) | 655 | static void fimc_job_abort(void *priv) |
636 | { | 656 | { |
637 | /* Nothing done in job_abort. */ | 657 | struct fimc_ctx *ctx = priv; |
658 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
659 | |||
660 | if (!fimc_m2m_pending(fimc)) | ||
661 | return; | ||
662 | |||
663 | set_bit(ST_M2M_SHUT, &fimc->state); | ||
664 | |||
665 | wait_event_timeout(fimc->irq_queue, | ||
666 | !test_bit(ST_M2M_SHUT, &fimc->state), | ||
667 | FIMC_SHUTDOWN_TIMEOUT); | ||
638 | } | 668 | } |
639 | 669 | ||
640 | static int fimc_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, | 670 | static int fimc_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, |
@@ -711,6 +741,7 @@ struct vb2_ops fimc_qops = { | |||
711 | .buf_queue = fimc_buf_queue, | 741 | .buf_queue = fimc_buf_queue, |
712 | .wait_prepare = fimc_unlock, | 742 | .wait_prepare = fimc_unlock, |
713 | .wait_finish = fimc_lock, | 743 | .wait_finish = fimc_lock, |
744 | .stop_streaming = stop_streaming, | ||
714 | }; | 745 | }; |
715 | 746 | ||
716 | static int fimc_m2m_querycap(struct file *file, void *priv, | 747 | static int fimc_m2m_querycap(struct file *file, void *priv, |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index 57bff0d21962..4829a2515076 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h | |||
@@ -57,6 +57,7 @@ enum fimc_dev_flags { | |||
57 | ST_IDLE, | 57 | ST_IDLE, |
58 | ST_OUTDMA_RUN, | 58 | ST_OUTDMA_RUN, |
59 | ST_M2M_PEND, | 59 | ST_M2M_PEND, |
60 | ST_M2M_SHUT, | ||
60 | /* for capture node */ | 61 | /* for capture node */ |
61 | ST_CAPT_PEND, | 62 | ST_CAPT_PEND, |
62 | ST_CAPT_RUN, | 63 | ST_CAPT_RUN, |