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

Commit 2cf1b502 authored by Mangalaram ARCHANA's avatar Mangalaram ARCHANA
Browse files

msm: camera: crm: Increase the device handles to 128



Increasing the device handles to 128 to support more pipelines.

Change-Id: Id0322cba095091e6168d8541d432628d8422a641
Signed-off-by: default avatarMangalaram ARCHANA <mangar@codeaurora.org>
parent ce294c74
Loading
Loading
Loading
Loading
+139 −21
Original line number Original line Diff line number Diff line
@@ -2364,7 +2364,7 @@ static struct cam_req_mgr_crm_cb cam_req_mgr_ops = {
 *
 *
 */
 */
static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
	struct cam_req_mgr_link_info *link_info)
	struct cam_req_mgr_ver_info *link_info)
{
{
	int                                     rc = 0, i = 0;
	int                                     rc = 0, i = 0;
	struct cam_req_mgr_core_dev_link_setup  link_data;
	struct cam_req_mgr_core_dev_link_setup  link_data;
@@ -2372,10 +2372,16 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
	struct cam_req_mgr_req_tbl             *pd_tbl;
	struct cam_req_mgr_req_tbl             *pd_tbl;
	enum cam_pipeline_delay                 max_delay;
	enum cam_pipeline_delay                 max_delay;
	uint32_t                                subscribe_event = 0;
	uint32_t                                subscribe_event = 0;

	if (link_info->version == VERSION_1) {
	if (link_info->num_devices > CAM_REQ_MGR_MAX_HANDLES)
		if (link_info->u.link_info_v1.num_devices >
			CAM_REQ_MGR_MAX_HANDLES)
			return -EPERM;
			return -EPERM;

		}
	else if (link_info->version == VERSION_2) {
		if (link_info->u.link_info_v2.num_devices >
			CAM_REQ_MGR_MAX_HANDLES_V2)
			return -EPERM;
		}
	mutex_init(&link->req.lock);
	mutex_init(&link->req.lock);
	CAM_DBG(CAM_CRM, "LOCK_DBG in_q lock %pK", &link->req.lock);
	CAM_DBG(CAM_CRM, "LOCK_DBG in_q lock %pK", &link->req.lock);
	link->req.num_tbl = 0;
	link->req.num_tbl = 0;
@@ -2385,11 +2391,12 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
		return rc;
		return rc;


	max_delay = CAM_PIPELINE_DELAY_0;
	max_delay = CAM_PIPELINE_DELAY_0;
	for (i = 0; i < link_info->num_devices; i++) {
	for (i = 0; i < link_info->u.link_info_v1.num_devices; i++) {
		dev = &link->l_dev[i];
		dev = &link->l_dev[i];
		/* Using dev hdl, get ops ptr to communicate with device */
		/* Using dev hdl, get ops ptr to communicate with device */
		dev->ops = (struct cam_req_mgr_kmd_ops *)
		dev->ops = (struct cam_req_mgr_kmd_ops *)
			cam_get_device_ops(link_info->dev_hdls[i]);
			cam_get_device_ops(
			link_info->u.link_info_v1.dev_hdls[i]);
		if (!dev->ops ||
		if (!dev->ops ||
			!dev->ops->get_dev_info ||
			!dev->ops->get_dev_info ||
			!dev->ops->link_setup) {
			!dev->ops->link_setup) {
@@ -2397,7 +2404,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
			rc = -ENXIO;
			rc = -ENXIO;
			goto error;
			goto error;
		}
		}
		dev->dev_hdl = link_info->dev_hdls[i];
		dev->dev_hdl = link_info->u.link_info_v1.dev_hdls[i];
		dev->parent = (void *)link;
		dev->parent = (void *)link;
		dev->dev_info.dev_hdl = dev->dev_hdl;
		dev->dev_info.dev_hdl = dev->dev_hdl;
		rc = dev->ops->get_dev_info(&dev->dev_info);
		rc = dev->ops->get_dev_info(&dev->dev_info);
@@ -2406,7 +2413,8 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,


		CAM_DBG(CAM_CRM,
		CAM_DBG(CAM_CRM,
			"%x: connected: %s, id %d, delay %d, trigger %x",
			"%x: connected: %s, id %d, delay %d, trigger %x",
			link_info->session_hdl, dev->dev_info.name,
			link_info->u.link_info_v1.session_hdl,
			dev->dev_info.name,
			dev->dev_info.dev_id, dev->dev_info.p_delay,
			dev->dev_info.dev_id, dev->dev_info.p_delay,
			dev->dev_info.trigger);
			dev->dev_info.trigger);
		if (rc < 0 ||
		if (rc < 0 ||
@@ -2418,7 +2426,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
			goto error;
			goto error;
		} else {
		} else {
			CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d",
			CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d",
				link_info->session_hdl,
				link_info->u.link_info_v1.session_hdl,
				dev->dev_info.name,
				dev->dev_info.name,
				dev->dev_info.p_delay);
				dev->dev_info.p_delay);
			if (dev->dev_info.p_delay > max_delay)
			if (dev->dev_info.p_delay > max_delay)
@@ -2435,7 +2443,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
	link_data.max_delay = max_delay;
	link_data.max_delay = max_delay;
	link_data.subscribe_event = subscribe_event;
	link_data.subscribe_event = subscribe_event;


	for (i = 0; i < link_info->num_devices; i++) {
	for (i = 0; i < link_info->u.link_info_v1.num_devices; i++) {
		dev = &link->l_dev[i];
		dev = &link->l_dev[i];


		link_data.dev_hdl = dev->dev_hdl;
		link_data.dev_hdl = dev->dev_hdl;
@@ -2478,7 +2486,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
		if (link->max_delay < dev->dev_info.p_delay)
		if (link->max_delay < dev->dev_info.p_delay)
			link->max_delay = dev->dev_info.p_delay;
			link->max_delay = dev->dev_info.p_delay;
	}
	}
	link->num_devs = link_info->num_devices;
	link->num_devs = link_info->u.link_info_v1.num_devices;


	/* Assign id for pd tables */
	/* Assign id for pd tables */
	__cam_req_mgr_tbl_set_id(link->req.l_tbl, &link->req);
	__cam_req_mgr_tbl_set_id(link->req.l_tbl, &link->req);
@@ -2636,7 +2644,115 @@ int cam_req_mgr_destroy_session(
	return rc;
	return rc;
}
}


int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)
int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info)
{
	int                                     rc = 0;
	int                                     wq_flag = 0;
	char                                    buf[128];
	struct cam_create_dev_hdl               root_dev;
	struct cam_req_mgr_core_session        *cam_session;
	struct cam_req_mgr_core_link           *link;

	if (!link_info) {
		CAM_DBG(CAM_CRM, "NULL pointer");
		return -EINVAL;
	}
	if (link_info->u.link_info_v1.num_devices > CAM_REQ_MGR_MAX_HANDLES) {
		CAM_ERR(CAM_CRM, "Invalid num devices %d",
			link_info->u.link_info_v1.num_devices);
		return -EINVAL;
	}

	mutex_lock(&g_crm_core_dev->crm_lock);

	/* session hdl's priv data is cam session struct */
	cam_session = (struct cam_req_mgr_core_session *)
		cam_get_device_priv(link_info->u.link_info_v1.session_hdl);
	if (!cam_session) {
		CAM_DBG(CAM_CRM, "NULL pointer");
		mutex_unlock(&g_crm_core_dev->crm_lock);
		return -EINVAL;
	}

	/* Allocate link struct and map it with session's request queue */
	link = __cam_req_mgr_reserve_link(cam_session);
	if (!link) {
		CAM_ERR(CAM_CRM, "failed to reserve new link");
		mutex_unlock(&g_crm_core_dev->crm_lock);
		return -EINVAL;
	}
	CAM_DBG(CAM_CRM, "link reserved %pK %x", link, link->link_hdl);

	memset(&root_dev, 0, sizeof(struct cam_create_dev_hdl));
	root_dev.session_hdl = link_info->u.link_info_v1.session_hdl;
	root_dev.priv = (void *)link;

	mutex_lock(&link->lock);
	/* Create unique dev handle for link */
	link->link_hdl = cam_create_device_hdl(&root_dev);
	if (link->link_hdl < 0) {
		CAM_ERR(CAM_CRM,
			"Insufficient memory to create new device handle");
		rc = link->link_hdl;
		goto link_hdl_fail;
	}
	link_info->u.link_info_v1.link_hdl = link->link_hdl;
	link->last_flush_id = 0;

	/* Allocate memory to hold data of all linked devs */
	rc = __cam_req_mgr_create_subdevs(&link->l_dev,
		link_info->u.link_info_v1.num_devices);
	if (rc < 0) {
		CAM_ERR(CAM_CRM,
			"Insufficient memory to create new crm subdevs");
		goto create_subdev_failed;
	}

	/* Using device ops query connected devs, prepare request tables */
	rc = __cam_req_mgr_setup_link_info(link, link_info);
	if (rc < 0)
		goto setup_failed;

	spin_lock_bh(&link->link_state_spin_lock);
	link->state = CAM_CRM_LINK_STATE_READY;
	spin_unlock_bh(&link->link_state_spin_lock);

	/* Create worker for current link */
	snprintf(buf, sizeof(buf), "%x-%x",
		link_info->u.link_info_v1.session_hdl, link->link_hdl);
	wq_flag = CAM_WORKQ_FLAG_HIGH_PRIORITY | CAM_WORKQ_FLAG_SERIAL;
	rc = cam_req_mgr_workq_create(buf, CRM_WORKQ_NUM_TASKS,
		&link->workq, CRM_WORKQ_USAGE_NON_IRQ, wq_flag);
	if (rc < 0) {
		CAM_ERR(CAM_CRM, "FATAL: unable to create worker");
		__cam_req_mgr_destroy_link_info(link);
		goto setup_failed;
	}

	/* Assign payload to workqueue tasks */
	rc = __cam_req_mgr_setup_payload(link->workq);
	if (rc < 0) {
		__cam_req_mgr_destroy_link_info(link);
		cam_req_mgr_workq_destroy(&link->workq);
		goto setup_failed;
	}

	mutex_unlock(&link->lock);
	mutex_unlock(&g_crm_core_dev->crm_lock);
	return rc;
setup_failed:
	__cam_req_mgr_destroy_subdev(link->l_dev);
create_subdev_failed:
	cam_destroy_device_hdl(link->link_hdl);
	link_info->u.link_info_v1.link_hdl = -1;
link_hdl_fail:
	mutex_unlock(&link->lock);
	__cam_req_mgr_unreserve_link(cam_session, link);
	mutex_unlock(&g_crm_core_dev->crm_lock);
	return rc;
}

int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info)
{
{
	int                                     rc = 0;
	int                                     rc = 0;
	int                                     wq_flag = 0;
	int                                     wq_flag = 0;
@@ -2649,9 +2765,10 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)
		CAM_DBG(CAM_CRM, "NULL pointer");
		CAM_DBG(CAM_CRM, "NULL pointer");
		return -EINVAL;
		return -EINVAL;
	}
	}
	if (link_info->num_devices > CAM_REQ_MGR_MAX_HANDLES) {
	if (link_info->u.link_info_v2.num_devices >
		CAM_REQ_MGR_MAX_HANDLES_V2) {
		CAM_ERR(CAM_CRM, "Invalid num devices %d",
		CAM_ERR(CAM_CRM, "Invalid num devices %d",
			link_info->num_devices);
			link_info->u.link_info_v2.num_devices);
		return -EINVAL;
		return -EINVAL;
	}
	}


@@ -2659,7 +2776,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)


	/* session hdl's priv data is cam session struct */
	/* session hdl's priv data is cam session struct */
	cam_session = (struct cam_req_mgr_core_session *)
	cam_session = (struct cam_req_mgr_core_session *)
		cam_get_device_priv(link_info->session_hdl);
		cam_get_device_priv(link_info->u.link_info_v2.session_hdl);
	if (!cam_session) {
	if (!cam_session) {
		CAM_DBG(CAM_CRM, "NULL pointer");
		CAM_DBG(CAM_CRM, "NULL pointer");
		mutex_unlock(&g_crm_core_dev->crm_lock);
		mutex_unlock(&g_crm_core_dev->crm_lock);
@@ -2676,7 +2793,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)
	CAM_DBG(CAM_CRM, "link reserved %pK %x", link, link->link_hdl);
	CAM_DBG(CAM_CRM, "link reserved %pK %x", link, link->link_hdl);


	memset(&root_dev, 0, sizeof(struct cam_create_dev_hdl));
	memset(&root_dev, 0, sizeof(struct cam_create_dev_hdl));
	root_dev.session_hdl = link_info->session_hdl;
	root_dev.session_hdl = link_info->u.link_info_v2.session_hdl;
	root_dev.priv = (void *)link;
	root_dev.priv = (void *)link;


	mutex_lock(&link->lock);
	mutex_lock(&link->lock);
@@ -2688,12 +2805,12 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)
		rc = link->link_hdl;
		rc = link->link_hdl;
		goto link_hdl_fail;
		goto link_hdl_fail;
	}
	}
	link_info->link_hdl = link->link_hdl;
	link_info->u.link_info_v2.link_hdl = link->link_hdl;
	link->last_flush_id = 0;
	link->last_flush_id = 0;


	/* Allocate memory to hold data of all linked devs */
	/* Allocate memory to hold data of all linked devs */
	rc = __cam_req_mgr_create_subdevs(&link->l_dev,
	rc = __cam_req_mgr_create_subdevs(&link->l_dev,
		link_info->num_devices);
		link_info->u.link_info_v2.num_devices);
	if (rc < 0) {
	if (rc < 0) {
		CAM_ERR(CAM_CRM,
		CAM_ERR(CAM_CRM,
			"Insufficient memory to create new crm subdevs");
			"Insufficient memory to create new crm subdevs");
@@ -2711,7 +2828,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)


	/* Create worker for current link */
	/* Create worker for current link */
	snprintf(buf, sizeof(buf), "%x-%x",
	snprintf(buf, sizeof(buf), "%x-%x",
		link_info->session_hdl, link->link_hdl);
		link_info->u.link_info_v2.session_hdl, link->link_hdl);
	wq_flag = CAM_WORKQ_FLAG_HIGH_PRIORITY | CAM_WORKQ_FLAG_SERIAL;
	wq_flag = CAM_WORKQ_FLAG_HIGH_PRIORITY | CAM_WORKQ_FLAG_SERIAL;
	rc = cam_req_mgr_workq_create(buf, CRM_WORKQ_NUM_TASKS,
	rc = cam_req_mgr_workq_create(buf, CRM_WORKQ_NUM_TASKS,
		&link->workq, CRM_WORKQ_USAGE_NON_IRQ, wq_flag);
		&link->workq, CRM_WORKQ_USAGE_NON_IRQ, wq_flag);
@@ -2736,7 +2853,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)
	__cam_req_mgr_destroy_subdev(link->l_dev);
	__cam_req_mgr_destroy_subdev(link->l_dev);
create_subdev_failed:
create_subdev_failed:
	cam_destroy_device_hdl(link->link_hdl);
	cam_destroy_device_hdl(link->link_hdl);
	link_info->link_hdl = -1;
	link_info->u.link_info_v2.link_hdl = -1;
link_hdl_fail:
link_hdl_fail:
	mutex_unlock(&link->lock);
	mutex_unlock(&link->lock);
	__cam_req_mgr_unreserve_link(cam_session, link);
	__cam_req_mgr_unreserve_link(cam_session, link);
@@ -2744,6 +2861,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)
	return rc;
	return rc;
}
}



int cam_req_mgr_unlink(struct cam_req_mgr_unlink_info *unlink_info)
int cam_req_mgr_unlink(struct cam_req_mgr_unlink_info *unlink_info)
{
{
	int                              rc = 0;
	int                              rc = 0;
+6 −1
Original line number Original line Diff line number Diff line
@@ -36,6 +36,9 @@


#define MAXIMUM_LINKS_PER_SESSION  4
#define MAXIMUM_LINKS_PER_SESSION  4


#define VERSION_1  1
#define VERSION_2  2

/**
/**
 * enum crm_workq_task_type
 * enum crm_workq_task_type
 * @codes: to identify which type of task is present
 * @codes: to identify which type of task is present
@@ -412,7 +415,9 @@ int cam_req_mgr_destroy_session(struct cam_req_mgr_session_info *ses_info);
 * a unique link handle for the link and is specific to a
 * a unique link handle for the link and is specific to a
 * session. Returns link handle
 * session. Returns link handle
 */
 */
int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info);
int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info);
int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info);



/**
/**
 * cam_req_mgr_unlink()
 * cam_req_mgr_unlink()
+30 −7
Original line number Original line Diff line number Diff line
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -268,27 +268,50 @@ static long cam_private_ioctl(struct file *file, void *fh,
		break;
		break;


	case CAM_REQ_MGR_LINK: {
	case CAM_REQ_MGR_LINK: {
		struct cam_req_mgr_link_info link_info;
		struct cam_req_mgr_ver_info ver_info;


		if (k_ioctl->size != sizeof(link_info))
		if (k_ioctl->size != sizeof(ver_info.u.link_info_v1))
			return -EINVAL;
			return -EINVAL;


		if (copy_from_user(&link_info,
		if (copy_from_user(&ver_info.u.link_info_v1,
			u64_to_user_ptr(k_ioctl->handle),
			u64_to_user_ptr(k_ioctl->handle),
			sizeof(struct cam_req_mgr_link_info))) {
			sizeof(struct cam_req_mgr_link_info))) {
			return -EFAULT;
			return -EFAULT;
		}
		}

		ver_info.version = VERSION_1;
		rc = cam_req_mgr_link(&link_info);
		rc = cam_req_mgr_link(&ver_info);
		if (!rc)
		if (!rc)
			if (copy_to_user(
			if (copy_to_user(
				u64_to_user_ptr(k_ioctl->handle),
				u64_to_user_ptr(k_ioctl->handle),
				&link_info,
				&ver_info.u.link_info_v1,
				sizeof(struct cam_req_mgr_link_info)))
				sizeof(struct cam_req_mgr_link_info)))
				rc = -EFAULT;
				rc = -EFAULT;
		}
		}
		break;
		break;


	case CAM_REQ_MGR_LINK_V2: {
			struct cam_req_mgr_ver_info ver_info;

			if (k_ioctl->size != sizeof(ver_info.u.link_info_v2))
				return -EINVAL;

			if (copy_from_user(&ver_info.u.link_info_v2,
				u64_to_user_ptr(k_ioctl->handle),
				sizeof(struct cam_req_mgr_link_info_v2))) {
				return -EFAULT;
			}
			ver_info.version = VERSION_2;
			rc = cam_req_mgr_link_v2(&ver_info);
			if (!rc)
				if (copy_to_user(
					u64_to_user_ptr(k_ioctl->handle),
					&ver_info.u.link_info_v2,
					sizeof(struct
						cam_req_mgr_link_info_v2)))
					rc = -EFAULT;
			}
			break;

	case CAM_REQ_MGR_UNLINK: {
	case CAM_REQ_MGR_UNLINK: {
		struct cam_req_mgr_unlink_info unlink_info;
		struct cam_req_mgr_unlink_info unlink_info;


+16 −0
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@
 * It includes both session and device handles
 * It includes both session and device handles
 */
 */
#define CAM_REQ_MGR_MAX_HANDLES           64
#define CAM_REQ_MGR_MAX_HANDLES           64
#define CAM_REQ_MGR_MAX_HANDLES_V2        128
#define MAX_LINKS_PER_SESSION             2
#define MAX_LINKS_PER_SESSION             2


/* V4L event type which user space will subscribe to */
/* V4L event type which user space will subscribe to */
@@ -121,6 +122,20 @@ struct cam_req_mgr_link_info {
	int32_t link_hdl;
	int32_t link_hdl;
};
};


struct cam_req_mgr_link_info_v2 {
	int32_t session_hdl;
	uint32_t num_devices;
	int32_t dev_hdls[CAM_REQ_MGR_MAX_HANDLES_V2];
	int32_t link_hdl;
};

struct cam_req_mgr_ver_info {
	uint32_t version;
	union {
		struct cam_req_mgr_link_info link_info_v1;
		struct cam_req_mgr_link_info_v2 link_info_v2;
	} u;
};
/**
/**
 * struct cam_req_mgr_unlink_info
 * struct cam_req_mgr_unlink_info
 * @session_hdl: input param - session handle
 * @session_hdl: input param - session handle
@@ -230,6 +245,7 @@ struct cam_req_mgr_link_control {
#define CAM_REQ_MGR_RELEASE_BUF                 (CAM_COMMON_OPCODE_MAX + 11)
#define CAM_REQ_MGR_RELEASE_BUF                 (CAM_COMMON_OPCODE_MAX + 11)
#define CAM_REQ_MGR_CACHE_OPS                   (CAM_COMMON_OPCODE_MAX + 12)
#define CAM_REQ_MGR_CACHE_OPS                   (CAM_COMMON_OPCODE_MAX + 12)
#define CAM_REQ_MGR_LINK_CONTROL                (CAM_COMMON_OPCODE_MAX + 13)
#define CAM_REQ_MGR_LINK_CONTROL                (CAM_COMMON_OPCODE_MAX + 13)
#define CAM_REQ_MGR_LINK_V2                     (CAM_COMMON_OPCODE_MAX + 14)
/* end of cam_req_mgr opcodes */
/* end of cam_req_mgr opcodes */


#define CAM_MEM_FLAG_HW_READ_WRITE              (1<<0)
#define CAM_MEM_FLAG_HW_READ_WRITE              (1<<0)