Loading drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c +139 −21 Original line number Diff line number Diff line Loading @@ -2378,7 +2378,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; Loading @@ -2386,10 +2386,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; Loading @@ -2399,11 +2405,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) { Loading @@ -2411,7 +2418,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); Loading @@ -2420,7 +2427,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 || Loading @@ -2432,7 +2440,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) Loading @@ -2449,7 +2457,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; Loading Loading @@ -2492,7 +2500,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); Loading Loading @@ -2650,7 +2658,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; Loading @@ -2663,9 +2779,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; } Loading @@ -2673,7 +2790,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); Loading @@ -2690,7 +2807,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); Loading @@ -2702,12 +2819,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"); Loading @@ -2725,7 +2842,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); Loading @@ -2750,7 +2867,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); Loading @@ -2758,6 +2875,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; Loading drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h +6 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,9 @@ #define MAXIMUM_LINKS_PER_SESSION 4 #define VERSION_1 1 #define VERSION_2 2 /** * enum crm_workq_task_type * @codes: to identify which type of task is present Loading Loading @@ -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 * 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() Loading drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c +30 −7 Original line number 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -268,27 +268,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; Loading include/uapi/media/cam_req_mgr.h +16 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,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 */ Loading Loading @@ -121,6 +122,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 Loading Loading @@ -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_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) Loading Loading
drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c +139 −21 Original line number Diff line number Diff line Loading @@ -2378,7 +2378,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; Loading @@ -2386,10 +2386,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; Loading @@ -2399,11 +2405,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) { Loading @@ -2411,7 +2418,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); Loading @@ -2420,7 +2427,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 || Loading @@ -2432,7 +2440,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) Loading @@ -2449,7 +2457,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; Loading Loading @@ -2492,7 +2500,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); Loading Loading @@ -2650,7 +2658,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; Loading @@ -2663,9 +2779,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; } Loading @@ -2673,7 +2790,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); Loading @@ -2690,7 +2807,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); Loading @@ -2702,12 +2819,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"); Loading @@ -2725,7 +2842,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); Loading @@ -2750,7 +2867,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); Loading @@ -2758,6 +2875,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; Loading
drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h +6 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,9 @@ #define MAXIMUM_LINKS_PER_SESSION 4 #define VERSION_1 1 #define VERSION_2 2 /** * enum crm_workq_task_type * @codes: to identify which type of task is present Loading Loading @@ -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 * 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() Loading
drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c +30 −7 Original line number 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -268,27 +268,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; Loading
include/uapi/media/cam_req_mgr.h +16 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,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 */ Loading Loading @@ -121,6 +122,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 Loading Loading @@ -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_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) Loading