diff options
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-lite.c | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-lite.c b/drivers/media/video/s5p-fimc/fimc-lite.c index 4d269b8fa1ef..74ff310db30c 100644 --- a/drivers/media/video/s5p-fimc/fimc-lite.c +++ b/drivers/media/video/s5p-fimc/fimc-lite.c | |||
@@ -453,34 +453,42 @@ static int fimc_lite_open(struct file *file) | |||
453 | struct fimc_lite *fimc = video_drvdata(file); | 453 | struct fimc_lite *fimc = video_drvdata(file); |
454 | int ret; | 454 | int ret; |
455 | 455 | ||
456 | if (mutex_lock_interruptible(&fimc->lock)) | ||
457 | return -ERESTARTSYS; | ||
458 | |||
456 | set_bit(ST_FLITE_IN_USE, &fimc->state); | 459 | set_bit(ST_FLITE_IN_USE, &fimc->state); |
457 | ret = pm_runtime_get_sync(&fimc->pdev->dev); | 460 | ret = pm_runtime_get_sync(&fimc->pdev->dev); |
458 | if (ret < 0) | 461 | if (ret < 0) |
459 | return ret; | 462 | goto done; |
460 | |||
461 | if (++fimc->ref_count != 1 || fimc->out_path != FIMC_IO_DMA) | ||
462 | return 0; | ||
463 | 463 | ||
464 | ret = v4l2_fh_open(file); | 464 | ret = v4l2_fh_open(file); |
465 | if (ret < 0) | 465 | if (ret < 0) |
466 | return ret; | 466 | goto done; |
467 | 467 | ||
468 | ret = fimc_pipeline_initialize(&fimc->pipeline, &fimc->vfd->entity, | 468 | if (++fimc->ref_count == 1 && fimc->out_path == FIMC_IO_DMA) { |
469 | true); | 469 | ret = fimc_pipeline_initialize(&fimc->pipeline, |
470 | if (ret < 0) { | 470 | &fimc->vfd->entity, true); |
471 | pm_runtime_put_sync(&fimc->pdev->dev); | 471 | if (ret < 0) { |
472 | fimc->ref_count--; | 472 | pm_runtime_put_sync(&fimc->pdev->dev); |
473 | v4l2_fh_release(file); | 473 | fimc->ref_count--; |
474 | clear_bit(ST_FLITE_IN_USE, &fimc->state); | 474 | v4l2_fh_release(file); |
475 | } | 475 | clear_bit(ST_FLITE_IN_USE, &fimc->state); |
476 | } | ||
476 | 477 | ||
477 | fimc_lite_clear_event_counters(fimc); | 478 | fimc_lite_clear_event_counters(fimc); |
479 | } | ||
480 | done: | ||
481 | mutex_unlock(&fimc->lock); | ||
478 | return ret; | 482 | return ret; |
479 | } | 483 | } |
480 | 484 | ||
481 | static int fimc_lite_close(struct file *file) | 485 | static int fimc_lite_close(struct file *file) |
482 | { | 486 | { |
483 | 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; | ||
484 | 492 | ||
485 | if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) { | 493 | if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) { |
486 | clear_bit(ST_FLITE_IN_USE, &fimc->state); | 494 | clear_bit(ST_FLITE_IN_USE, &fimc->state); |
@@ -494,20 +502,39 @@ static int fimc_lite_close(struct file *file) | |||
494 | if (fimc->ref_count == 0) | 502 | if (fimc->ref_count == 0) |
495 | vb2_queue_release(&fimc->vb_queue); | 503 | vb2_queue_release(&fimc->vb_queue); |
496 | 504 | ||
497 | return v4l2_fh_release(file); | 505 | ret = v4l2_fh_release(file); |
506 | |||
507 | mutex_unlock(&fimc->lock); | ||
508 | return ret; | ||
498 | } | 509 | } |
499 | 510 | ||
500 | static unsigned int fimc_lite_poll(struct file *file, | 511 | static unsigned int fimc_lite_poll(struct file *file, |
501 | struct poll_table_struct *wait) | 512 | struct poll_table_struct *wait) |
502 | { | 513 | { |
503 | struct fimc_lite *fimc = video_drvdata(file); | 514 | struct fimc_lite *fimc = video_drvdata(file); |
504 | 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; | ||
505 | } | 524 | } |
506 | 525 | ||
507 | 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) |
508 | { | 527 | { |
509 | struct fimc_lite *fimc = video_drvdata(file); | 528 | struct fimc_lite *fimc = video_drvdata(file); |
510 | 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; | ||
511 | } | 538 | } |
512 | 539 | ||
513 | static const struct v4l2_file_operations fimc_lite_fops = { | 540 | static const struct v4l2_file_operations fimc_lite_fops = { |