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

Commit 6761503d authored by Jigarkumar Zala's avatar Jigarkumar Zala Committed by Gerrit - the friendly Code Review server
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>
Signed-off-by: default avatarJigarkumar Zala <jzala@codeaurora.org>
parent 4767766e
Loading
Loading
Loading
Loading
+139 −21
Original line number Diff line number Diff line
@@ -2438,7 +2438,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,
	struct cam_req_mgr_link_info *link_info)
	struct cam_req_mgr_ver_info *link_info)
{
	int                                     rc = 0, i = 0;
	struct cam_req_mgr_core_dev_link_setup  link_data;
@@ -2446,10 +2446,16 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
	struct cam_req_mgr_req_tbl             *pd_tbl;
	enum cam_pipeline_delay                 max_delay;
	uint32_t                                subscribe_event = 0;

	if (link_info->num_devices > CAM_REQ_MGR_MAX_HANDLES)
	if (link_info->version == VERSION_1) {
		if (link_info->u.link_info_v1.num_devices >
			CAM_REQ_MGR_MAX_HANDLES)
			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);
	CAM_DBG(CAM_CRM, "LOCK_DBG in_q lock %pK", &link->req.lock);
	link->req.num_tbl = 0;
@@ -2459,11 +2465,12 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
		return rc;

	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];
		/* Using dev hdl, get ops ptr to communicate with device */
		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 ||
			!dev->ops->get_dev_info ||
			!dev->ops->link_setup) {
@@ -2471,7 +2478,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
			rc = -ENXIO;
			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->dev_info.dev_hdl = dev->dev_hdl;
		rc = dev->ops->get_dev_info(&dev->dev_info);
@@ -2480,7 +2487,8 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,

		CAM_DBG(CAM_CRM,
			"%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.trigger);
		if (rc < 0 ||
@@ -2492,7 +2500,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
			goto error;
		} else {
			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.p_delay);
			if (dev->dev_info.p_delay > max_delay)
@@ -2509,7 +2517,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
	link_data.max_delay = max_delay;
	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];

		link_data.dev_hdl = dev->dev_hdl;
@@ -2552,7 +2560,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)
			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 */
	__cam_req_mgr_tbl_set_id(link->req.l_tbl, &link->req);
@@ -2710,7 +2718,115 @@ int cam_req_mgr_destroy_session(
	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                                     wq_flag = 0;
@@ -2723,9 +2839,10 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)
		CAM_DBG(CAM_CRM, "NULL pointer");
		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",
			link_info->num_devices);
			link_info->u.link_info_v2.num_devices);
		return -EINVAL;
	}

@@ -2733,7 +2850,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)

	/* session hdl's priv data is cam session struct */
	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) {
		CAM_DBG(CAM_CRM, "NULL pointer");
		mutex_unlock(&g_crm_core_dev->crm_lock);
@@ -2750,7 +2867,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);

	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;

	mutex_lock(&link->lock);
@@ -2762,12 +2879,12 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)
		rc = link->link_hdl;
		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;

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

	/* Create worker for current link */
	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;
	rc = cam_req_mgr_workq_create(buf, CRM_WORKQ_NUM_TASKS,
		&link->workq, CRM_WORKQ_USAGE_NON_IRQ, wq_flag);
@@ -2810,7 +2927,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)
	__cam_req_mgr_destroy_subdev(link->l_dev);
create_subdev_failed:
	cam_destroy_device_hdl(link->link_hdl);
	link_info->link_hdl = -1;
	link_info->u.link_info_v2.link_hdl = -1;
link_hdl_fail:
	mutex_unlock(&link->lock);
	__cam_req_mgr_unreserve_link(cam_session, link);
@@ -2818,6 +2935,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)
	return rc;
}


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

#define MAXIMUM_RETRY_ATTEMPTS 3

#define VERSION_1  1
#define VERSION_2  2

/**
 * enum crm_workq_task_type
 * @codes: to identify which type of task is present
@@ -408,7 +411,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
 * 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()
+30 −7
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 */

#include <linux/module.h>
@@ -261,27 +261,50 @@ static long cam_private_ioctl(struct file *file, void *fh,
		break;

	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;

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

		rc = cam_req_mgr_link(&link_info);
		ver_info.version = VERSION_1;
		rc = cam_req_mgr_link(&ver_info);
		if (!rc)
			if (copy_to_user(
				u64_to_user_ptr(k_ioctl->handle),
				&link_info,
				&ver_info.u.link_info_v1,
				sizeof(struct cam_req_mgr_link_info)))
				rc = -EFAULT;
		}
		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: {
		struct cam_req_mgr_unlink_info unlink_info;

+17 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
/*
 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 */

#ifndef __UAPI_LINUX_CAM_REQ_MGR_H
@@ -40,6 +40,7 @@
 * It includes both session and device handles
 */
#define CAM_REQ_MGR_MAX_HANDLES           64
#define CAM_REQ_MGR_MAX_HANDLES_V2        128
#define MAX_LINKS_PER_SESSION             2

/* V4L event type which user space will subscribe to */
@@ -126,6 +127,20 @@ struct cam_req_mgr_link_info {
	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
 * @session_hdl: input param - session handle
@@ -235,6 +250,7 @@ struct cam_req_mgr_link_control {
#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_LINK_CONTROL                (CAM_COMMON_OPCODE_MAX + 13)
#define CAM_REQ_MGR_LINK_V2                     (CAM_COMMON_OPCODE_MAX + 14)
/* end of cam_req_mgr opcodes */

#define CAM_MEM_FLAG_HW_READ_WRITE              (1<<0)