Merge "msm: camera: Add proper error handling during msm_open" into msm-3.0
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 175a441..8d59590 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -1366,6 +1366,14 @@
return rc;
}
+ /* The number of camera instance should be controlled by the
+ resource manager. Currently supporting one active instance
+ until multiple instances are supported */
+ if (atomic_read(&ps->number_pcam_active) > 0) {
+ pr_err("%s Cannot have more than one active camera %d\n",
+ __func__, atomic_read(&ps->number_pcam_active));
+ return -EINVAL;
+ }
/* book keeping this camera session*/
ps->pcam_active = pcam;
atomic_inc(&ps->number_pcam_active);
@@ -1411,6 +1419,9 @@
{
int i;
int rc = -EINVAL;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ int ion_client_created = 0;
+#endif
/*struct msm_isp_ops *p_isp = 0;*/
/* get the video device */
struct msm_cam_v4l2_device *pcam = video_drvdata(f);
@@ -1442,7 +1453,9 @@
pcam_inst->pcam = pcam;
pcam->dev_inst[i] = pcam_inst;
- D("%s for %s\n", __func__, pcam->pdev->name);
+ D("%s index %d nodeid %d count %d\n", __func__,
+ pcam_inst->my_index,
+ pcam->vnode_id, pcam->use_count);
pcam->use_count++;
if (pcam->use_count == 1) {
@@ -1450,19 +1463,19 @@
if (rc < 0) {
pr_err("%s: cam_server_open_session failed %d\n",
__func__, rc);
- mutex_unlock(&pcam->vid_lock);
- return rc;
+ goto err;
}
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
pcam->mctl.client = msm_ion_client_create(-1, "camera");
kref_init(&pcam->mctl.refcount);
+ ion_client_created = 1;
#endif
/* Should be set to sensor ops if any but right now its OK!! */
if (!pcam->mctl.mctl_open) {
D("%s: media contoller is not inited\n",
__func__);
- mutex_unlock(&pcam->vid_lock);
- return -ENODEV;
+ rc = -ENODEV;
+ goto err;
}
/* Now we really have to activate the camera */
@@ -1470,9 +1483,8 @@
rc = pcam->mctl.mctl_open(&(pcam->mctl), MSM_APPS_ID_V4L2);
if (rc < 0) {
- mutex_unlock(&pcam->vid_lock);
pr_err("%s: HW open failed rc = 0x%x\n", __func__, rc);
- return rc;
+ goto err;
}
pcam->mctl.sync.pcam_sync = pcam;
@@ -1480,24 +1492,21 @@
rc = v4l2_device_register_subdev(&pcam->v4l2_dev,
pcam->mctl.isp_sdev->sd);
if (rc < 0) {
- mutex_unlock(&pcam->vid_lock);
pr_err("%s: v4l2_device_register_subdev failed rc = %d\n",
__func__, rc);
- return rc;
+ goto err;
}
if (pcam->mctl.isp_sdev->sd_vpe) {
rc = v4l2_device_register_subdev(&pcam->v4l2_dev,
pcam->mctl.isp_sdev->sd_vpe);
if (rc < 0) {
- mutex_unlock(&pcam->vid_lock);
- return rc;
+ goto err;
}
}
rc = msm_setup_v4l2_event_queue(&pcam_inst->eventHandle,
pcam->pvdev);
if (rc < 0) {
- mutex_unlock(&pcam->vid_lock);
- return rc;
+ goto err;
}
}
pcam_inst->vbqueue_initialized = 0;
@@ -1522,6 +1531,21 @@
D("%s: end", __func__);
/* rc = msm_cam_server_open_session(g_server_dev, pcam);*/
return rc;
+
+err:
+ if (pcam->use_count == 1) {
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ if (ion_client_created) {
+ pr_err("%s: destroy ion client", __func__);
+ kref_put(&pcam->mctl.refcount, msm_release_ion_client);
+ }
+#endif
+ pcam->dev_inst[i] = NULL;
+ pcam->use_count = 0;
+ }
+ mutex_unlock(&pcam->vid_lock);
+ kfree(pcam_inst);
+ return rc;
}
static int msm_addr_remap(struct msm_cam_v4l2_dev_inst *pcam_inst,
@@ -1622,6 +1646,8 @@
if (pcam_inst->vbqueue_initialized)
vb2_queue_release(&pcam_inst->vid_bufq);
D("%s Closing down instance %p ", __func__, pcam_inst);
+ D("%s index %d nodeid %d count %d\n", __func__, pcam_inst->my_index,
+ pcam->vnode_id, pcam->use_count);
pcam->dev_inst[pcam_inst->my_index] = NULL;
if (pcam_inst->my_index == 0) {
v4l2_fh_del(&pcam_inst->eventHandle);
@@ -2638,7 +2664,7 @@
D("%s done, rc = %d\n", __func__, rc);
D("%s number of sensors connected is %d\n", __func__,
- g_server_dev.camera_info.num_cameras);
+ g_server_dev.camera_info.num_cameras);
/* register the subdevice, must be done for callbacks */
rc = v4l2_device_register_subdev(&pcam->v4l2_dev, sensor_sd);