aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/s5p-fimc/fimc-lite.c61
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 }
480done:
481 mutex_unlock(&fimc->lock);
478 return ret; 482 return ret;
479} 483}
480 484
481static int fimc_lite_close(struct file *file) 485static 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
500static unsigned int fimc_lite_poll(struct file *file, 511static 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
507static int fimc_lite_mmap(struct file *file, struct vm_area_struct *vma) 526static 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
513static const struct v4l2_file_operations fimc_lite_fops = { 540static const struct v4l2_file_operations fimc_lite_fops = {