aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c22
-rw-r--r--include/media/soc_camera.h2
2 files changed, 20 insertions, 4 deletions
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index a8ca956e7a40..1070a0c496d8 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -517,7 +517,14 @@ static int soc_camera_open(struct file *file)
517 /* No device driver attached */ 517 /* No device driver attached */
518 return -ENODEV; 518 return -ENODEV;
519 519
520 /*
521 * Don't mess with the host during probe: wait until the loop in
522 * scan_add_host() completes
523 */
524 if (mutex_lock_interruptible(&list_lock))
525 return -ERESTARTSYS;
520 ici = to_soc_camera_host(icd->parent); 526 ici = to_soc_camera_host(icd->parent);
527 mutex_unlock(&list_lock);
521 528
522 if (mutex_lock_interruptible(&icd->video_lock)) 529 if (mutex_lock_interruptible(&icd->video_lock))
523 return -ERESTARTSYS; 530 return -ERESTARTSYS;
@@ -548,7 +555,6 @@ static int soc_camera_open(struct file *file)
548 if (icl->reset) 555 if (icl->reset)
549 icl->reset(icd->pdev); 556 icl->reset(icd->pdev);
550 557
551 /* Don't mess with the host during probe */
552 mutex_lock(&ici->host_lock); 558 mutex_lock(&ici->host_lock);
553 ret = ici->ops->add(icd); 559 ret = ici->ops->add(icd);
554 mutex_unlock(&ici->host_lock); 560 mutex_unlock(&ici->host_lock);
@@ -602,7 +608,9 @@ esfmt:
602eresume: 608eresume:
603 __soc_camera_power_off(icd); 609 __soc_camera_power_off(icd);
604epower: 610epower:
611 mutex_lock(&ici->host_lock);
605 ici->ops->remove(icd); 612 ici->ops->remove(icd);
613 mutex_unlock(&ici->host_lock);
606eiciadd: 614eiciadd:
607 icd->use_count--; 615 icd->use_count--;
608 module_put(ici->ops->owner); 616 module_put(ici->ops->owner);
@@ -625,7 +633,9 @@ static int soc_camera_close(struct file *file)
625 633
626 if (ici->ops->init_videobuf2) 634 if (ici->ops->init_videobuf2)
627 vb2_queue_release(&icd->vb2_vidq); 635 vb2_queue_release(&icd->vb2_vidq);
636 mutex_lock(&ici->host_lock);
628 ici->ops->remove(icd); 637 ici->ops->remove(icd);
638 mutex_unlock(&ici->host_lock);
629 639
630 __soc_camera_power_off(icd); 640 __soc_camera_power_off(icd);
631 } 641 }
@@ -1052,7 +1062,7 @@ static void scan_add_host(struct soc_camera_host *ici)
1052{ 1062{
1053 struct soc_camera_device *icd; 1063 struct soc_camera_device *icd;
1054 1064
1055 mutex_lock(&ici->host_lock); 1065 mutex_lock(&list_lock);
1056 1066
1057 list_for_each_entry(icd, &devices, list) { 1067 list_for_each_entry(icd, &devices, list) {
1058 if (icd->iface == ici->nr) { 1068 if (icd->iface == ici->nr) {
@@ -1061,7 +1071,7 @@ static void scan_add_host(struct soc_camera_host *ici)
1061 } 1071 }
1062 } 1072 }
1063 1073
1064 mutex_unlock(&ici->host_lock); 1074 mutex_unlock(&list_lock);
1065} 1075}
1066 1076
1067#ifdef CONFIG_I2C_BOARDINFO 1077#ifdef CONFIG_I2C_BOARDINFO
@@ -1148,7 +1158,9 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1148 if (icl->reset) 1158 if (icl->reset)
1149 icl->reset(icd->pdev); 1159 icl->reset(icd->pdev);
1150 1160
1161 mutex_lock(&ici->host_lock);
1151 ret = ici->ops->add(icd); 1162 ret = ici->ops->add(icd);
1163 mutex_unlock(&ici->host_lock);
1152 if (ret < 0) 1164 if (ret < 0)
1153 goto eadd; 1165 goto eadd;
1154 1166
@@ -1220,7 +1232,9 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1220 icd->field = mf.field; 1232 icd->field = mf.field;
1221 } 1233 }
1222 1234
1235 mutex_lock(&ici->host_lock);
1223 ici->ops->remove(icd); 1236 ici->ops->remove(icd);
1237 mutex_unlock(&ici->host_lock);
1224 1238
1225 mutex_unlock(&icd->video_lock); 1239 mutex_unlock(&icd->video_lock);
1226 1240
@@ -1242,7 +1256,9 @@ eadddev:
1242 video_device_release(icd->vdev); 1256 video_device_release(icd->vdev);
1243 icd->vdev = NULL; 1257 icd->vdev = NULL;
1244evdc: 1258evdc:
1259 mutex_lock(&ici->host_lock);
1245 ici->ops->remove(icd); 1260 ici->ops->remove(icd);
1261 mutex_unlock(&ici->host_lock);
1246eadd: 1262eadd:
1247ereg: 1263ereg:
1248 v4l2_ctrl_handler_free(&icd->ctrl_handler); 1264 v4l2_ctrl_handler_free(&icd->ctrl_handler);
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 6442edc2a151..0370a9517282 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -62,7 +62,7 @@ struct soc_camera_device {
62struct soc_camera_host { 62struct soc_camera_host {
63 struct v4l2_device v4l2_dev; 63 struct v4l2_device v4l2_dev;
64 struct list_head list; 64 struct list_head list;
65 struct mutex host_lock; /* Protect during probing */ 65 struct mutex host_lock; /* Protect pipeline modifications */
66 unsigned char nr; /* Host number */ 66 unsigned char nr; /* Host number */
67 u32 capabilities; 67 u32 capabilities;
68 void *priv; 68 void *priv;