aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/soc_camera/soc_camera.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/soc_camera/soc_camera.c')
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c48
1 files changed, 31 insertions, 17 deletions
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index 8ec98051ea73..eea832c5fd01 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -256,12 +256,12 @@ static int soc_camera_s_input(struct file *file, void *priv, unsigned int i)
256 return 0; 256 return 0;
257} 257}
258 258
259static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a) 259static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id a)
260{ 260{
261 struct soc_camera_device *icd = file->private_data; 261 struct soc_camera_device *icd = file->private_data;
262 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 262 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
263 263
264 return v4l2_subdev_call(sd, core, s_std, *a); 264 return v4l2_subdev_call(sd, core, s_std, a);
265} 265}
266 266
267static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a) 267static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a)
@@ -508,36 +508,49 @@ static int soc_camera_set_fmt(struct soc_camera_device *icd,
508static int soc_camera_open(struct file *file) 508static int soc_camera_open(struct file *file)
509{ 509{
510 struct video_device *vdev = video_devdata(file); 510 struct video_device *vdev = video_devdata(file);
511 struct soc_camera_device *icd = dev_get_drvdata(vdev->parent); 511 struct soc_camera_device *icd;
512 struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
513 struct soc_camera_host *ici; 512 struct soc_camera_host *ici;
514 int ret; 513 int ret;
515 514
516 if (!to_soc_camera_control(icd))
517 /* No device driver attached */
518 return -ENODEV;
519
520 /* 515 /*
521 * Don't mess with the host during probe: wait until the loop in 516 * Don't mess with the host during probe: wait until the loop in
522 * scan_add_host() completes 517 * scan_add_host() completes. Also protect against a race with
518 * soc_camera_host_unregister().
523 */ 519 */
524 if (mutex_lock_interruptible(&list_lock)) 520 if (mutex_lock_interruptible(&list_lock))
525 return -ERESTARTSYS; 521 return -ERESTARTSYS;
522
523 if (!vdev || !video_is_registered(vdev)) {
524 mutex_unlock(&list_lock);
525 return -ENODEV;
526 }
527
528 icd = dev_get_drvdata(vdev->parent);
526 ici = to_soc_camera_host(icd->parent); 529 ici = to_soc_camera_host(icd->parent);
530
531 ret = try_module_get(ici->ops->owner) ? 0 : -ENODEV;
527 mutex_unlock(&list_lock); 532 mutex_unlock(&list_lock);
528 533
529 if (mutex_lock_interruptible(&ici->host_lock)) 534 if (ret < 0) {
530 return -ERESTARTSYS;
531 if (!try_module_get(ici->ops->owner)) {
532 dev_err(icd->pdev, "Couldn't lock capture bus driver.\n"); 535 dev_err(icd->pdev, "Couldn't lock capture bus driver.\n");
533 ret = -EINVAL; 536 return ret;
534 goto emodule;
535 } 537 }
536 538
539 if (!to_soc_camera_control(icd)) {
540 /* No device driver attached */
541 ret = -ENODEV;
542 goto econtrol;
543 }
544
545 if (mutex_lock_interruptible(&ici->host_lock)) {
546 ret = -ERESTARTSYS;
547 goto elockhost;
548 }
537 icd->use_count++; 549 icd->use_count++;
538 550
539 /* Now we really have to activate the camera */ 551 /* Now we really have to activate the camera */
540 if (icd->use_count == 1) { 552 if (icd->use_count == 1) {
553 struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
541 /* Restore parameters before the last close() per V4L2 API */ 554 /* Restore parameters before the last close() per V4L2 API */
542 struct v4l2_format f = { 555 struct v4l2_format f = {
543 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 556 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
@@ -609,9 +622,10 @@ epower:
609 ici->ops->remove(icd); 622 ici->ops->remove(icd);
610eiciadd: 623eiciadd:
611 icd->use_count--; 624 icd->use_count--;
612 module_put(ici->ops->owner);
613emodule:
614 mutex_unlock(&ici->host_lock); 625 mutex_unlock(&ici->host_lock);
626elockhost:
627econtrol:
628 module_put(ici->ops->owner);
615 629
616 return ret; 630 return ret;
617} 631}
@@ -1042,7 +1056,7 @@ static int soc_camera_g_register(struct file *file, void *fh,
1042} 1056}
1043 1057
1044static int soc_camera_s_register(struct file *file, void *fh, 1058static int soc_camera_s_register(struct file *file, void *fh,
1045 struct v4l2_dbg_register *reg) 1059 const struct v4l2_dbg_register *reg)
1046{ 1060{
1047 struct soc_camera_device *icd = file->private_data; 1061 struct soc_camera_device *icd = file->private_data;
1048 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1062 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);