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,
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;

View File

@ -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()

View File

@ -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 <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;

View File

@ -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)