diff options
Diffstat (limited to 'drivers/media/video/s5p-fimc/fimc-lite.c')
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-lite.c | 73 |
1 files changed, 52 insertions, 21 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-lite.c b/drivers/media/video/s5p-fimc/fimc-lite.c index 400d701aef04..74ff310db30c 100644 --- a/drivers/media/video/s5p-fimc/fimc-lite.c +++ b/drivers/media/video/s5p-fimc/fimc-lite.c | |||
@@ -451,34 +451,44 @@ static void fimc_lite_clear_event_counters(struct fimc_lite *fimc) | |||
451 | static int fimc_lite_open(struct file *file) | 451 | static int fimc_lite_open(struct file *file) |
452 | { | 452 | { |
453 | struct fimc_lite *fimc = video_drvdata(file); | 453 | struct fimc_lite *fimc = video_drvdata(file); |
454 | int ret = v4l2_fh_open(file); | 454 | int ret; |
455 | 455 | ||
456 | if (ret) | 456 | if (mutex_lock_interruptible(&fimc->lock)) |
457 | return ret; | 457 | return -ERESTARTSYS; |
458 | 458 | ||
459 | set_bit(ST_FLITE_IN_USE, &fimc->state); | 459 | set_bit(ST_FLITE_IN_USE, &fimc->state); |
460 | pm_runtime_get_sync(&fimc->pdev->dev); | 460 | ret = pm_runtime_get_sync(&fimc->pdev->dev); |
461 | if (ret < 0) | ||
462 | goto done; | ||
461 | 463 | ||
462 | if (++fimc->ref_count != 1 || fimc->out_path != FIMC_IO_DMA) | 464 | ret = v4l2_fh_open(file); |
463 | return ret; | 465 | if (ret < 0) |
466 | goto done; | ||
464 | 467 | ||
465 | ret = fimc_pipeline_initialize(&fimc->pipeline, &fimc->vfd->entity, | 468 | if (++fimc->ref_count == 1 && fimc->out_path == FIMC_IO_DMA) { |
466 | true); | 469 | ret = fimc_pipeline_initialize(&fimc->pipeline, |
467 | if (ret < 0) { | 470 | &fimc->vfd->entity, true); |
468 | v4l2_err(fimc->vfd, "Video pipeline initialization failed\n"); | 471 | if (ret < 0) { |
469 | pm_runtime_put_sync(&fimc->pdev->dev); | 472 | pm_runtime_put_sync(&fimc->pdev->dev); |
470 | fimc->ref_count--; | 473 | fimc->ref_count--; |
471 | v4l2_fh_release(file); | 474 | v4l2_fh_release(file); |
472 | clear_bit(ST_FLITE_IN_USE, &fimc->state); | 475 | clear_bit(ST_FLITE_IN_USE, &fimc->state); |
473 | } | 476 | } |
474 | 477 | ||
475 | fimc_lite_clear_event_counters(fimc); | 478 | fimc_lite_clear_event_counters(fimc); |
479 | } | ||
480 | done: | ||
481 | mutex_unlock(&fimc->lock); | ||
476 | return ret; | 482 | return ret; |
477 | } | 483 | } |
478 | 484 | ||
479 | static int fimc_lite_close(struct file *file) | 485 | static int fimc_lite_close(struct file *file) |
480 | { | 486 | { |
481 | struct fimc_lite *fimc = video_drvdata(file); | 487 | struct fimc_lite *fimc = video_drvdata(file); |
488 | int ret; | ||
489 | |||
490 | if (mutex_lock_interruptible(&fimc->lock)) | ||
491 | return -ERESTARTSYS; | ||
482 | 492 | ||
483 | if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) { | 493 | if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) { |
484 | clear_bit(ST_FLITE_IN_USE, &fimc->state); | 494 | clear_bit(ST_FLITE_IN_USE, &fimc->state); |
@@ -492,20 +502,39 @@ static int fimc_lite_close(struct file *file) | |||
492 | if (fimc->ref_count == 0) | 502 | if (fimc->ref_count == 0) |
493 | vb2_queue_release(&fimc->vb_queue); | 503 | vb2_queue_release(&fimc->vb_queue); |
494 | 504 | ||
495 | return v4l2_fh_release(file); | 505 | ret = v4l2_fh_release(file); |
506 | |||
507 | mutex_unlock(&fimc->lock); | ||
508 | return ret; | ||
496 | } | 509 | } |
497 | 510 | ||
498 | static unsigned int fimc_lite_poll(struct file *file, | 511 | static unsigned int fimc_lite_poll(struct file *file, |
499 | struct poll_table_struct *wait) | 512 | struct poll_table_struct *wait) |
500 | { | 513 | { |
501 | struct fimc_lite *fimc = video_drvdata(file); | 514 | struct fimc_lite *fimc = video_drvdata(file); |
502 | return vb2_poll(&fimc->vb_queue, file, wait); | 515 | int ret; |
516 | |||
517 | if (mutex_lock_interruptible(&fimc->lock)) | ||
518 | return POLL_ERR; | ||
519 | |||
520 | ret = vb2_poll(&fimc->vb_queue, file, wait); | ||
521 | mutex_unlock(&fimc->lock); | ||
522 | |||
523 | return ret; | ||
503 | } | 524 | } |
504 | 525 | ||
505 | static int fimc_lite_mmap(struct file *file, struct vm_area_struct *vma) | 526 | static int fimc_lite_mmap(struct file *file, struct vm_area_struct *vma) |
506 | { | 527 | { |
507 | struct fimc_lite *fimc = video_drvdata(file); | 528 | struct fimc_lite *fimc = video_drvdata(file); |
508 | return vb2_mmap(&fimc->vb_queue, vma); | 529 | int ret; |
530 | |||
531 | if (mutex_lock_interruptible(&fimc->lock)) | ||
532 | return -ERESTARTSYS; | ||
533 | |||
534 | ret = vb2_mmap(&fimc->vb_queue, vma); | ||
535 | mutex_unlock(&fimc->lock); | ||
536 | |||
537 | return ret; | ||
509 | } | 538 | } |
510 | 539 | ||
511 | static const struct v4l2_file_operations fimc_lite_fops = { | 540 | static const struct v4l2_file_operations fimc_lite_fops = { |
@@ -762,7 +791,9 @@ static int fimc_lite_streamon(struct file *file, void *priv, | |||
762 | if (fimc_lite_active(fimc)) | 791 | if (fimc_lite_active(fimc)) |
763 | return -EBUSY; | 792 | return -EBUSY; |
764 | 793 | ||
765 | media_entity_pipeline_start(&sensor->entity, p->m_pipeline); | 794 | ret = media_entity_pipeline_start(&sensor->entity, p->m_pipeline); |
795 | if (ret < 0) | ||
796 | return ret; | ||
766 | 797 | ||
767 | ret = fimc_pipeline_validate(fimc); | 798 | ret = fimc_pipeline_validate(fimc); |
768 | if (ret) { | 799 | if (ret) { |
@@ -1508,7 +1539,7 @@ static int fimc_lite_suspend(struct device *dev) | |||
1508 | return 0; | 1539 | return 0; |
1509 | 1540 | ||
1510 | ret = fimc_lite_stop_capture(fimc, suspend); | 1541 | ret = fimc_lite_stop_capture(fimc, suspend); |
1511 | if (ret) | 1542 | if (ret < 0 || !fimc_lite_active(fimc)) |
1512 | return ret; | 1543 | return ret; |
1513 | 1544 | ||
1514 | return fimc_pipeline_shutdown(&fimc->pipeline); | 1545 | return fimc_pipeline_shutdown(&fimc->pipeline); |