From 6761503d24604eb8f518fa1d415ae6a60d97668f Mon Sep 17 00:00:00 2001 From: Jigarkumar Zala Date: Mon, 29 Jul 2019 13:21:20 -0700 Subject: [PATCH] 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: Mangalaram ARCHANA Signed-off-by: Jigarkumar Zala --- drivers/cam_req_mgr/cam_req_mgr_core.c | 160 +++++++++++++++++++++---- drivers/cam_req_mgr/cam_req_mgr_core.h | 7 +- drivers/cam_req_mgr/cam_req_mgr_dev.c | 37 ++++-- include/uapi/media/cam_req_mgr.h | 18 ++- 4 files changed, 192 insertions(+), 30 deletions(-) diff --git a/drivers/cam_req_mgr/cam_req_mgr_core.c b/drivers/cam_req_mgr/cam_req_mgr_core.c index 6e660a393824..f4867d5d828e 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/cam_req_mgr/cam_req_mgr_core.c @@ -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) - return -EPERM; - + 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,7 @@ end: 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; @@ -2723,9 +2731,9 @@ 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_v1.num_devices > CAM_REQ_MGR_MAX_HANDLES) { CAM_ERR(CAM_CRM, "Invalid num devices %d", - link_info->num_devices); + link_info->u.link_info_v1.num_devices); return -EINVAL; } @@ -2733,7 +2741,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_v1.session_hdl); if (!cam_session) { CAM_DBG(CAM_CRM, "NULL pointer"); mutex_unlock(&g_crm_core_dev->crm_lock); @@ -2750,7 +2758,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_v1.session_hdl; root_dev.priv = (void *)link; mutex_lock(&link->lock); @@ -2762,12 +2770,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_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->num_devices); + link_info->u.link_info_v1.num_devices); if (rc < 0) { CAM_ERR(CAM_CRM, "Insufficient memory to create new crm subdevs"); @@ -2785,7 +2793,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_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); @@ -2810,7 +2818,7 @@ setup_failed: __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_v1.link_hdl = -1; link_hdl_fail: mutex_unlock(&link->lock); __cam_req_mgr_unreserve_link(cam_session, link); @@ -2818,6 +2826,116 @@ link_hdl_fail: return rc; } +int cam_req_mgr_link_v2(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_v2.num_devices > + CAM_REQ_MGR_MAX_HANDLES_V2) { + CAM_ERR(CAM_CRM, "Invalid num devices %d", + link_info->u.link_info_v2.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_v2.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_v2.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_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->u.link_info_v2.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_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); + 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_v2.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_unlink(struct cam_req_mgr_unlink_info *unlink_info) { int rc = 0; diff --git a/drivers/cam_req_mgr/cam_req_mgr_core.h b/drivers/cam_req_mgr/cam_req_mgr_core.h index 9a6acbc2c43e..8eb15bec802d 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_core.h +++ b/drivers/cam_req_mgr/cam_req_mgr_core.h @@ -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() diff --git a/drivers/cam_req_mgr/cam_req_mgr_dev.c b/drivers/cam_req_mgr/cam_req_mgr_dev.c index 74d5cfff8d60..b1a05cc14b9a 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_dev.c +++ b/drivers/cam_req_mgr/cam_req_mgr_dev.c @@ -1,6 +1,6 @@ // 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 @@ -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; diff --git a/include/uapi/media/cam_req_mgr.h b/include/uapi/media/cam_req_mgr.h index f495eb883fcd..a8c12e2d7c0d 100644 --- a/include/uapi/media/cam_req_mgr.h +++ b/include/uapi/media/cam_req_mgr.h @@ -1,6 +1,6 @@ /* 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)