Merge "msm: camera: crm: Increase the device handles to 128" into camera-kernel.lnx.1.0

This commit is contained in:
Pavan Kumar Chilamkurthi 2019-08-06 15:13:34 -07:00 committed by Gerrit - the friendly Code Review server
commit eb6763f590
4 changed files with 192 additions and 30 deletions

View File

@ -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, 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;
@ -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; 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 >
return -EPERM; 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); 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;
@ -2459,11 +2465,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) {
@ -2471,7 +2478,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);
@ -2480,7 +2487,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 ||
@ -2492,7 +2500,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)
@ -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.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;
@ -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) 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);
@ -2710,7 +2718,7 @@ end:
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 rc = 0;
int wq_flag = 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"); 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_v1.num_devices > CAM_REQ_MGR_MAX_HANDLES) {
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_v1.num_devices);
return -EINVAL; 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 */ /* 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_v1.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);
@ -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); 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_v1.session_hdl;
root_dev.priv = (void *)link; root_dev.priv = (void *)link;
mutex_lock(&link->lock); 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; rc = link->link_hdl;
goto link_hdl_fail; 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; 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_v1.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");
@ -2785,7 +2793,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_v1.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);
@ -2810,7 +2818,7 @@ setup_failed:
__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_v1.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);
@ -2818,6 +2826,116 @@ link_hdl_fail:
return rc; 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 cam_req_mgr_unlink(struct cam_req_mgr_unlink_info *unlink_info)
{ {
int rc = 0; int rc = 0;

View File

@ -31,6 +31,9 @@
#define MAXIMUM_RETRY_ATTEMPTS 3 #define MAXIMUM_RETRY_ATTEMPTS 3
#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
@ -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 * 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()

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // 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> #include <linux/module.h>
@ -261,27 +261,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;

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* 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 #ifndef __UAPI_LINUX_CAM_REQ_MGR_H
@ -40,6 +40,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 */
@ -126,6 +127,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
@ -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_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)