Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 695e0730 authored by Camera Software Integration's avatar Camera Software Integration Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: common: Fix failures in v4l2 unregister during error" into...

Merge "msm: camera: common: Fix failures in v4l2 unregister during error" into camera-kernel.lnx.4.0
parents 3fb2481c 0a649b30
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -205,7 +205,7 @@ static int cam_icp_component_bind(struct device *dev,
	g_icp_dev.open_cnt = 0;
	mutex_init(&g_icp_dev.icp_lock);

	CAM_DBG(CAM_ICP, "Component bound successfully");
	CAM_INFO(CAM_ICP, "Component bound successfully");

	return rc;

+1 −1
Original line number Diff line number Diff line
@@ -161,7 +161,7 @@ static int cam_isp_dev_component_bind(struct device *dev,

	mutex_init(&g_isp_dev.isp_mutex);

	CAM_INFO(CAM_ISP, "ISP HW component bound successfully");
	CAM_INFO(CAM_ISP, "Component bound successfully");

	return 0;
unregister:
+73 −30
Original line number Diff line number Diff line
@@ -62,8 +62,8 @@ static int cam_media_device_setup(struct device *dev)

static void cam_media_device_cleanup(void)
{
	media_entity_cleanup(&g_dev.video->entity);
	media_device_unregister(g_dev.v4l2_dev->mdev);
	media_device_cleanup(g_dev.v4l2_dev->mdev);
	kfree(g_dev.v4l2_dev->mdev);
	g_dev.v4l2_dev->mdev = NULL;
}
@@ -575,7 +575,7 @@ static int cam_video_device_setup(void)

	strlcpy(g_dev.video->name, "cam-req-mgr",
		sizeof(g_dev.video->name));
	g_dev.video->release = video_device_release;
	g_dev.video->release = video_device_release_empty;
	g_dev.video->fops = &g_cam_fops;
	g_dev.video->ioctl_ops = &g_cam_ioctl_ops;
	g_dev.video->minor = -1;
@@ -630,6 +630,7 @@ EXPORT_SYMBOL(cam_req_mgr_notify_message);

void cam_video_device_cleanup(void)
{
	media_entity_cleanup(&g_dev.video->entity);
	video_unregister_device(g_dev.video);
	video_device_release(g_dev.video);
	g_dev.video = NULL;
@@ -640,7 +641,7 @@ int cam_register_subdev(struct cam_subdev *csd)
	struct v4l2_subdev *sd;
	int rc;

	if (g_dev.state != true) {
	if (!g_dev.state) {
		CAM_ERR(CAM_CRM, "camera root device not ready yet");
		return -ENODEV;
	}
@@ -651,6 +652,15 @@ int cam_register_subdev(struct cam_subdev *csd)
	}

	mutex_lock(&g_dev.dev_lock);
	if ((g_dev.subdev_nodes_created) &&
		(csd->sd_flags & V4L2_SUBDEV_FL_HAS_DEVNODE)) {
		CAM_ERR(CAM_CRM,
			"dynamic node is not allowed, name: %s, type :%d",
			csd->name, csd->ent_function);
		rc = -EINVAL;
		goto reg_fail;
	}

	sd = &csd->sd;
	v4l2_subdev_init(sd, csd->ops);
	sd->internal_ops = csd->internal_ops;
@@ -662,34 +672,12 @@ int cam_register_subdev(struct cam_subdev *csd)
	sd->entity.pads = NULL;
	sd->entity.function = csd->ent_function;

	if (csd->subdev_node_created) {
		CAM_ERR(CAM_CRM,
			"Dynamic Node is not allowed, name: %s, type: %d",
			csd->name, csd->ent_function);
		rc = -EINVAL;
		goto reg_fail;
	}

	rc = v4l2_device_register_subdev(g_dev.v4l2_dev, sd);
	if (rc) {
		CAM_ERR(CAM_CRM, "register subdev failed");
		goto reg_fail;
	}

	rc = v4l2_device_register_subdev_nodes(g_dev.v4l2_dev);
	if (rc) {
		CAM_ERR(CAM_CRM,
			"Device Register subdev node failed: rc = %d", rc);
		goto reg_fail;

	}

	if ((sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE)) {
		sd->entity.name = video_device_node_name(sd->devnode);
		CAM_DBG(CAM_CRM, "created node :%s", sd->entity.name);
	}

	csd->subdev_node_created = true;
	g_dev.count++;

reg_fail:
@@ -700,7 +688,7 @@ EXPORT_SYMBOL(cam_register_subdev);

int cam_unregister_subdev(struct cam_subdev *csd)
{
	if (g_dev.state != true) {
	if (!g_dev.state) {
		CAM_ERR(CAM_CRM, "camera root device not ready yet");
		return -ENODEV;
	}
@@ -714,6 +702,47 @@ int cam_unregister_subdev(struct cam_subdev *csd)
}
EXPORT_SYMBOL(cam_unregister_subdev);

static int cam_dev_mgr_create_subdev_nodes(void)
{
	int rc;
	struct v4l2_subdev *sd;

	if (!g_dev.v4l2_dev) {
		CAM_ERR(CAM_CRM, "V4L2 device not initialized");
		return -EINVAL;
	}

	if (!g_dev.state) {
		CAM_ERR(CAM_CRM, "camera root device not ready");
		return -ENODEV;
	}

	mutex_lock(&g_dev.dev_lock);
	if (g_dev.subdev_nodes_created) {
		rc = -EEXIST;
		goto create_fail;
	}

	rc = v4l2_device_register_subdev_nodes(g_dev.v4l2_dev);
	if (rc) {
		CAM_ERR(CAM_CRM, "failed to register the sub devices");
		goto create_fail;
	}

	list_for_each_entry(sd, &g_dev.v4l2_dev->subdevs, list) {
		if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
			continue;
		sd->entity.name = video_device_node_name(sd->devnode);
		CAM_DBG(CAM_CRM, "created node :%s", sd->entity.name);
	}

	g_dev.subdev_nodes_created = true;

create_fail:
	mutex_unlock(&g_dev.dev_lock);
	return rc;
}

static int cam_req_mgr_component_master_bind(struct device *dev)
{
	int rc = 0;
@@ -734,6 +763,7 @@ static int cam_req_mgr_component_master_bind(struct device *dev)
	g_dev.open_cnt = 0;
	mutex_init(&g_dev.cam_lock);
	spin_lock_init(&g_dev.cam_eventq_lock);
	g_dev.subdev_nodes_created = false;
	mutex_init(&g_dev.dev_lock);

	rc = cam_req_mgr_util_init();
@@ -748,6 +778,8 @@ static int cam_req_mgr_component_master_bind(struct device *dev)
		goto req_mgr_core_fail;
	}

	g_dev.state = true;

	if (g_cam_req_mgr_timer_cachep == NULL) {
		g_cam_req_mgr_timer_cachep = kmem_cache_create("crm_timer",
			sizeof(struct cam_req_mgr_timer), 64,
@@ -761,19 +793,28 @@ static int cam_req_mgr_component_master_bind(struct device *dev)
				g_cam_req_mgr_timer_cachep->name);
	}

	g_dev.state = true;

	CAM_DBG(CAM_CRM, "Binding all slave components");
	CAM_INFO(CAM_CRM, "All probes done, binding slave components");
	rc = component_bind_all(dev, NULL);
	if (rc) {
		CAM_ERR(CAM_CRM,
			"Error in binding all components rc: %d, Camera initialization failed!",
			rc);
		goto req_mgr_core_fail;
		goto req_mgr_device_deinit;
	}

	rc = cam_dev_mgr_create_subdev_nodes();
	if (rc) {
		CAM_ERR(CAM_CRM, "failed in creating devices for subdevs %d",
			rc);
		goto req_mgr_device_deinit;
	}

	CAM_INFO(CAM_CRM, "All camera components bound successfully");

	return rc;

req_mgr_device_deinit:
	cam_req_mgr_core_device_deinit();
req_mgr_core_fail:
	cam_req_mgr_util_deinit();
req_mgr_util_fail:
@@ -784,6 +825,7 @@ static int cam_req_mgr_component_master_bind(struct device *dev)
	cam_media_device_cleanup();
media_setup_fail:
	cam_v4l2_device_cleanup();
	g_dev.state = false;
	return rc;
}

@@ -800,6 +842,7 @@ static void cam_req_mgr_component_master_unbind(struct device *dev)
	cam_v4l2_device_cleanup();
	mutex_destroy(&g_dev.dev_lock);
	g_dev.state = false;
	g_dev.subdev_nodes_created = false;
}

static const struct component_master_ops cam_req_mgr_component_master_ops = {
+2 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
 *
 * @video: pointer to struct video device.
 * @v4l2_dev: pointer to struct v4l2 device.
 * @subdev_nodes_created: all subdev nodes are created for this device
 * @count: number of subdevices registered.
 * @dev_lock: lock for the subdevice count.
 * @state: state of the root device.
@@ -23,6 +24,7 @@
struct cam_req_mgr_device {
	struct video_device *video;
	struct v4l2_device *v4l2_dev;
	bool subdev_nodes_created;
	int count;
	struct mutex dev_lock;
	bool state;
+0 −2
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@
 * @ent_function:          Media entity function type. Can be:
 *                             %CAM_IFE_DEVICE_TYPE - identifies as IFE device.
 *                             %CAM_ICP_DEVICE_TYPE - identifies as ICP device.
 * @subdev_node_created:   Enabled sub-device
 *
 * Each instance of a subdev driver should create this struct, either
 * stand-alone or embedded in a larger struct. This structure should be
@@ -50,7 +49,6 @@ struct cam_subdev {
	u32                                    sd_flags;
	void                                  *token;
	u32                                    ent_function;
	bool                                   subdev_node_created;
};

/**
Loading