Merge "msm: camera: req_mgr: Enhance camera v4l2 subdev shutdown sequence" into camera-kernel.lnx.5.0
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
68de607556
@@ -610,6 +610,31 @@ int cam_context_handle_stop_dev(struct cam_context *ctx,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cam_context_handle_shutdown_dev(struct cam_context *ctx,
|
||||||
|
struct cam_control *cmd, struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!ctx || !ctx->state_machine) {
|
||||||
|
CAM_ERR(CAM_CORE, "Context is not ready");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cmd) {
|
||||||
|
CAM_ERR(CAM_CORE, "Invalid stop device command payload");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->state_machine[ctx->state].ioctl_ops.shutdown_dev)
|
||||||
|
rc = ctx->state_machine[ctx->state].ioctl_ops.shutdown_dev(
|
||||||
|
(struct v4l2_subdev *)cmd->handle, fh);
|
||||||
|
else
|
||||||
|
CAM_WARN(CAM_CORE, "No shutdown device in dev %d, state %d",
|
||||||
|
ctx->dev_hdl, ctx->state);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
int cam_context_handle_info_dump(void *context,
|
int cam_context_handle_info_dump(void *context,
|
||||||
enum cam_context_dump_id id)
|
enum cam_context_dump_id id)
|
||||||
{
|
{
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/spinlock_types.h>
|
#include <linux/spinlock_types.h>
|
||||||
#include <linux/kref.h>
|
#include <linux/kref.h>
|
||||||
|
#include <media/v4l2-subdev.h>
|
||||||
#include "cam_req_mgr_interface.h"
|
#include "cam_req_mgr_interface.h"
|
||||||
#include "cam_hw_mgr_intf.h"
|
#include "cam_hw_mgr_intf.h"
|
||||||
#include "cam_smmu_api.h"
|
#include "cam_smmu_api.h"
|
||||||
@@ -97,6 +98,7 @@ struct cam_ctx_request {
|
|||||||
* @acquire_hw: Function pointer for acquire hw
|
* @acquire_hw: Function pointer for acquire hw
|
||||||
* @release_hw: Function pointer for release hw
|
* @release_hw: Function pointer for release hw
|
||||||
* @dump_dev: Function pointer for dump dev
|
* @dump_dev: Function pointer for dump dev
|
||||||
|
* @shutdown_dev: Function pointer for shutdown dev
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct cam_ctx_ioctl_ops {
|
struct cam_ctx_ioctl_ops {
|
||||||
@@ -116,6 +118,8 @@ struct cam_ctx_ioctl_ops {
|
|||||||
int (*release_hw)(struct cam_context *ctx, void *args);
|
int (*release_hw)(struct cam_context *ctx, void *args);
|
||||||
int (*dump_dev)(struct cam_context *ctx,
|
int (*dump_dev)(struct cam_context *ctx,
|
||||||
struct cam_dump_req_cmd *cmd);
|
struct cam_dump_req_cmd *cmd);
|
||||||
|
int (*shutdown_dev)(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -513,6 +517,19 @@ int cam_context_handle_start_dev(struct cam_context *ctx,
|
|||||||
int cam_context_handle_stop_dev(struct cam_context *ctx,
|
int cam_context_handle_stop_dev(struct cam_context *ctx,
|
||||||
struct cam_start_stop_dev_cmd *cmd);
|
struct cam_start_stop_dev_cmd *cmd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cam_context_handle_shutdown_dev()
|
||||||
|
*
|
||||||
|
* @brief: Handle shutdown device command
|
||||||
|
*
|
||||||
|
* @ctx: Object pointer for cam_context
|
||||||
|
* @cmd: Shutdown device command payload
|
||||||
|
* @fh: Pointer to struct v4l2_subdev_fh
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int cam_context_handle_shutdown_dev(struct cam_context *ctx,
|
||||||
|
struct cam_control *cmd, struct v4l2_subdev_fh *fh);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cam_context_handle_dump_dev()
|
* cam_context_handle_dump_dev()
|
||||||
*
|
*
|
||||||
|
@@ -297,6 +297,27 @@ static int __cam_node_handle_stop_dev(struct cam_node *node,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cam_node_handle_shutdown_dev(struct cam_node *node,
|
||||||
|
struct cam_control *cmd, struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
struct cam_context *ctx = NULL;
|
||||||
|
int32_t dev_index = -1;
|
||||||
|
int rc = 0, ret = 0;
|
||||||
|
|
||||||
|
while ((dev_index = cam_get_dev_handle_info(cmd->handle,
|
||||||
|
&ctx, dev_index)) < CAM_REQ_MGR_MAX_HANDLES_V2) {
|
||||||
|
ret = cam_context_handle_shutdown_dev(ctx, cmd, fh);
|
||||||
|
if (ret) {
|
||||||
|
rc = ret;
|
||||||
|
CAM_ERR(CAM_CORE, "Shutdown failure for node %s",
|
||||||
|
node->name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int __cam_node_handle_config_dev(struct cam_node *node,
|
static int __cam_node_handle_config_dev(struct cam_node *node,
|
||||||
struct cam_config_dev_cmd *config)
|
struct cam_config_dev_cmd *config)
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CAM_NODE_H_
|
#ifndef _CAM_NODE_H_
|
||||||
@@ -100,4 +100,30 @@ int cam_node_init(struct cam_node *node, struct cam_hw_mgr_intf *hw_mgr_intf,
|
|||||||
*/
|
*/
|
||||||
void cam_node_put_ctxt_to_free_list(struct kref *ref);
|
void cam_node_put_ctxt_to_free_list(struct kref *ref);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cam_get_dev_handle_info()
|
||||||
|
*
|
||||||
|
* @brief: provides the active dev index.
|
||||||
|
*
|
||||||
|
* @handle: pointer to struct v4l2_dev
|
||||||
|
* @ctx: pointer to struct cam_context
|
||||||
|
* @dev_index: dev index
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int32_t cam_get_dev_handle_info(uint64_t handle,
|
||||||
|
struct cam_context **ctx, int32_t dev_index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cam_node_handle_shutdown_dev()
|
||||||
|
*
|
||||||
|
* @brief: Shutdowns all the active devices.
|
||||||
|
*
|
||||||
|
* @node: pointer to struct node
|
||||||
|
* @cmd: pointer to struct cmd
|
||||||
|
* @fh: pointer to struct v4l2_subdev_fh
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int cam_node_handle_shutdown_dev(struct cam_node *node,
|
||||||
|
struct cam_control *cmd, struct v4l2_subdev_fh *fh);
|
||||||
|
|
||||||
#endif /* _CAM_NODE_H_ */
|
#endif /* _CAM_NODE_H_ */
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cam_subdev.h"
|
#include "cam_subdev.h"
|
||||||
@@ -45,6 +45,8 @@ static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd,
|
|||||||
long rc;
|
long rc;
|
||||||
struct cam_node *node =
|
struct cam_node *node =
|
||||||
(struct cam_node *) v4l2_get_subdevdata(sd);
|
(struct cam_node *) v4l2_get_subdevdata(sd);
|
||||||
|
struct v4l2_subdev_fh *fh = (struct v4l2_subdev_fh *)arg;
|
||||||
|
struct cam_control cntrl_cmd;
|
||||||
|
|
||||||
if (!node || node->state == CAM_NODE_STATE_UNINIT) {
|
if (!node || node->state == CAM_NODE_STATE_UNINIT) {
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
@@ -56,6 +58,19 @@ static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd,
|
|||||||
rc = cam_node_handle_ioctl(node,
|
rc = cam_node_handle_ioctl(node,
|
||||||
(struct cam_control *) arg);
|
(struct cam_control *) arg);
|
||||||
break;
|
break;
|
||||||
|
case CAM_SD_SHUTDOWN:
|
||||||
|
if (!cam_req_mgr_is_shutdown()) {
|
||||||
|
CAM_WARN(CAM_CORE, "SD shouldn't come from user space");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cntrl_cmd.op_code = CAM_SD_SHUTDOWN;
|
||||||
|
cntrl_cmd.handle = (uint64_t)sd;
|
||||||
|
rc = cam_node_handle_shutdown_dev(node, &cntrl_cmd, fh);
|
||||||
|
if (rc)
|
||||||
|
CAM_ERR(CAM_CORE, "shutdown device failed(rc = %d)",
|
||||||
|
rc);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
CAM_ERR(CAM_CORE, "Invalid command %d for %s", cmd,
|
CAM_ERR(CAM_CORE, "Invalid command %d for %s", cmd,
|
||||||
node->name);
|
node->name);
|
||||||
|
@@ -779,7 +779,7 @@ static int cam_cpas_subdev_open(struct v4l2_subdev *sd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cam_cpas_subdev_close(struct v4l2_subdev *sd,
|
static int __cam_cpas_subdev_close(struct v4l2_subdev *sd,
|
||||||
struct v4l2_subdev_fh *fh)
|
struct v4l2_subdev_fh *fh)
|
||||||
{
|
{
|
||||||
struct cam_cpas_intf *cpas_intf = v4l2_get_subdevdata(sd);
|
struct cam_cpas_intf *cpas_intf = v4l2_get_subdevdata(sd);
|
||||||
@@ -790,6 +790,11 @@ static int cam_cpas_subdev_close(struct v4l2_subdev *sd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&cpas_intf->intf_lock);
|
mutex_lock(&cpas_intf->intf_lock);
|
||||||
|
if (cpas_intf->open_cnt <= 0) {
|
||||||
|
CAM_WARN(CAM_CPAS, "device already closed, open_cnt: %d", cpas_intf->open_cnt);
|
||||||
|
mutex_unlock(&cpas_intf->intf_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
cpas_intf->open_cnt--;
|
cpas_intf->open_cnt--;
|
||||||
CAM_DBG(CAM_CPAS, "CPAS Subdev close count %d", cpas_intf->open_cnt);
|
CAM_DBG(CAM_CPAS, "CPAS Subdev close count %d", cpas_intf->open_cnt);
|
||||||
mutex_unlock(&cpas_intf->intf_lock);
|
mutex_unlock(&cpas_intf->intf_lock);
|
||||||
@@ -797,6 +802,19 @@ static int cam_cpas_subdev_close(struct v4l2_subdev *sd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cam_cpas_subdev_close(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
bool crm_active = cam_req_mgr_is_open(CAM_CPAS);
|
||||||
|
|
||||||
|
if (crm_active) {
|
||||||
|
CAM_DBG(CAM_CPAS, "CRM is ACTIVE, close should be from CRM");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return __cam_cpas_subdev_close(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
static long cam_cpas_subdev_ioctl(struct v4l2_subdev *sd,
|
static long cam_cpas_subdev_ioctl(struct v4l2_subdev *sd,
|
||||||
unsigned int cmd, void *arg)
|
unsigned int cmd, void *arg)
|
||||||
{
|
{
|
||||||
@@ -812,6 +830,9 @@ static long cam_cpas_subdev_ioctl(struct v4l2_subdev *sd,
|
|||||||
case VIDIOC_CAM_CONTROL:
|
case VIDIOC_CAM_CONTROL:
|
||||||
rc = cam_cpas_subdev_cmd(cpas_intf, (struct cam_control *) arg);
|
rc = cam_cpas_subdev_cmd(cpas_intf, (struct cam_control *) arg);
|
||||||
break;
|
break;
|
||||||
|
case CAM_SD_SHUTDOWN:
|
||||||
|
rc = __cam_cpas_subdev_close(sd, NULL);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
CAM_ERR(CAM_CPAS, "Invalid command %d for CPAS!", cmd);
|
CAM_ERR(CAM_CPAS, "Invalid command %d for CPAS!", cmd);
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
@@ -899,6 +920,7 @@ static int cam_cpas_subdev_register(struct platform_device *pdev)
|
|||||||
subdev->sd_flags =
|
subdev->sd_flags =
|
||||||
V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
|
V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
|
||||||
subdev->ent_function = CAM_CPAS_DEVICE_TYPE;
|
subdev->ent_function = CAM_CPAS_DEVICE_TYPE;
|
||||||
|
subdev->close_seq_prior = CAM_SD_CLOSE_LOW_PRIORITY;
|
||||||
|
|
||||||
rc = cam_register_subdev(subdev);
|
rc = cam_register_subdev(subdev);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@@ -1605,6 +1605,19 @@ static int __cam_custom_ctx_apply_default_req(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __cam_custom_ctx_shutdown_dev(
|
||||||
|
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
int rc = -EINVAL;
|
||||||
|
|
||||||
|
if (!sd || !fh) {
|
||||||
|
CAM_ERR(CAM_CUSTOM, "Invalid input pointer");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cam_custom_subdev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
/* top state machine */
|
/* top state machine */
|
||||||
static struct cam_ctx_ops
|
static struct cam_ctx_ops
|
||||||
cam_custom_dev_ctx_top_state_machine[CAM_CTX_STATE_MAX] = {
|
cam_custom_dev_ctx_top_state_machine[CAM_CTX_STATE_MAX] = {
|
||||||
@@ -1619,6 +1632,7 @@ static struct cam_ctx_ops
|
|||||||
.ioctl_ops = {
|
.ioctl_ops = {
|
||||||
.acquire_dev =
|
.acquire_dev =
|
||||||
__cam_custom_ctx_acquire_dev_in_available,
|
__cam_custom_ctx_acquire_dev_in_available,
|
||||||
|
.shutdown_dev = __cam_custom_ctx_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = NULL,
|
.irq_ops = NULL,
|
||||||
@@ -1630,6 +1644,7 @@ static struct cam_ctx_ops
|
|||||||
.release_dev = __cam_custom_release_dev_in_acquired,
|
.release_dev = __cam_custom_release_dev_in_acquired,
|
||||||
.config_dev = __cam_custom_ctx_config_dev_in_acquired,
|
.config_dev = __cam_custom_ctx_config_dev_in_acquired,
|
||||||
.release_hw = __cam_custom_ctx_release_hw_in_top_state,
|
.release_hw = __cam_custom_ctx_release_hw_in_top_state,
|
||||||
|
.shutdown_dev = __cam_custom_ctx_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {
|
.crm_ops = {
|
||||||
.link = __cam_custom_ctx_link_in_acquired,
|
.link = __cam_custom_ctx_link_in_acquired,
|
||||||
@@ -1648,6 +1663,7 @@ static struct cam_ctx_ops
|
|||||||
.release_dev = __cam_custom_release_dev_in_acquired,
|
.release_dev = __cam_custom_release_dev_in_acquired,
|
||||||
.config_dev = __cam_custom_ctx_config_dev,
|
.config_dev = __cam_custom_ctx_config_dev,
|
||||||
.release_hw = __cam_custom_ctx_release_hw_in_top_state,
|
.release_hw = __cam_custom_ctx_release_hw_in_top_state,
|
||||||
|
.shutdown_dev = __cam_custom_ctx_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {
|
.crm_ops = {
|
||||||
.unlink = __cam_custom_ctx_unlink_in_ready,
|
.unlink = __cam_custom_ctx_unlink_in_ready,
|
||||||
@@ -1665,6 +1681,7 @@ static struct cam_ctx_ops
|
|||||||
.config_dev = __cam_custom_ctx_config_dev_in_flushed,
|
.config_dev = __cam_custom_ctx_config_dev_in_flushed,
|
||||||
.release_hw =
|
.release_hw =
|
||||||
__cam_custom_ctx_release_hw_in_activated_state,
|
__cam_custom_ctx_release_hw_in_activated_state,
|
||||||
|
.shutdown_dev = __cam_custom_ctx_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {
|
.crm_ops = {
|
||||||
.unlink = __cam_custom_ctx_unlink_in_ready,
|
.unlink = __cam_custom_ctx_unlink_in_ready,
|
||||||
@@ -1681,6 +1698,7 @@ static struct cam_ctx_ops
|
|||||||
.config_dev = __cam_custom_ctx_config_dev,
|
.config_dev = __cam_custom_ctx_config_dev,
|
||||||
.release_hw =
|
.release_hw =
|
||||||
__cam_custom_ctx_release_hw_in_activated_state,
|
__cam_custom_ctx_release_hw_in_activated_state,
|
||||||
|
.shutdown_dev = __cam_custom_ctx_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {
|
.crm_ops = {
|
||||||
.unlink = __cam_custom_ctx_unlink_in_activated,
|
.unlink = __cam_custom_ctx_unlink_in_activated,
|
||||||
|
@@ -150,4 +150,16 @@ int cam_custom_dev_context_init(struct cam_custom_context *ctx,
|
|||||||
*/
|
*/
|
||||||
int cam_custom_dev_context_deinit(struct cam_custom_context *ctx);
|
int cam_custom_dev_context_deinit(struct cam_custom_context *ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cam_custom_subdev_close_internal()
|
||||||
|
*
|
||||||
|
* @brief: Close function for the Custom context
|
||||||
|
*
|
||||||
|
* @sd: Pointer to struct v4l2_subdev
|
||||||
|
* @fh: Pointer to struct v4l2_subdev_fh
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int cam_custom_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh);
|
||||||
|
|
||||||
#endif /* _CAM_CUSTOM_CONTEXT_H_ */
|
#endif /* _CAM_CUSTOM_CONTEXT_H_ */
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
@@ -58,7 +58,7 @@ static int cam_custom_subdev_open(struct v4l2_subdev *sd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cam_custom_subdev_close(struct v4l2_subdev *sd,
|
int cam_custom_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
struct v4l2_subdev_fh *fh)
|
struct v4l2_subdev_fh *fh)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -86,6 +86,19 @@ end:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cam_custom_subdev_close(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
bool crm_active = cam_req_mgr_is_open(CAM_CUSTOM);
|
||||||
|
|
||||||
|
if (crm_active) {
|
||||||
|
CAM_DBG(CAM_CUSTOM, "CRM is ACTIVE, close should be from CRM");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cam_custom_subdev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct v4l2_subdev_internal_ops cam_custom_subdev_internal_ops = {
|
static const struct v4l2_subdev_internal_ops cam_custom_subdev_internal_ops = {
|
||||||
.close = cam_custom_subdev_close,
|
.close = cam_custom_subdev_close,
|
||||||
.open = cam_custom_subdev_open,
|
.open = cam_custom_subdev_open,
|
||||||
@@ -102,6 +115,7 @@ static int cam_custom_component_bind(struct device *dev,
|
|||||||
struct platform_device *pdev = to_platform_device(dev);
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
|
|
||||||
g_custom_dev.sd.internal_ops = &cam_custom_subdev_internal_ops;
|
g_custom_dev.sd.internal_ops = &cam_custom_subdev_internal_ops;
|
||||||
|
g_custom_dev.sd.close_seq_prior = CAM_SD_CLOSE_HIGH_PRIORITY;
|
||||||
|
|
||||||
rc = cam_subdev_probe(&g_custom_dev.sd, pdev, CAM_CUSTOM_DEV_NAME,
|
rc = cam_subdev_probe(&g_custom_dev.sd, pdev, CAM_CUSTOM_DEV_NAME,
|
||||||
CAM_CUSTOM_DEVICE_TYPE);
|
CAM_CUSTOM_DEVICE_TYPE);
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
@@ -169,6 +169,19 @@ static int __cam_fd_ctx_handle_irq_in_activated(void *context,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __cam_fd_shutdown_dev(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
int rc = -EINVAL;
|
||||||
|
|
||||||
|
if (!sd || !fh) {
|
||||||
|
CAM_ERR(CAM_FD, "Invalid input pointer");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cam_fd_dev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
/* top state machine */
|
/* top state machine */
|
||||||
static struct cam_ctx_ops
|
static struct cam_ctx_ops
|
||||||
cam_fd_ctx_state_machine[CAM_CTX_STATE_MAX] = {
|
cam_fd_ctx_state_machine[CAM_CTX_STATE_MAX] = {
|
||||||
@@ -182,6 +195,7 @@ static struct cam_ctx_ops
|
|||||||
{
|
{
|
||||||
.ioctl_ops = {
|
.ioctl_ops = {
|
||||||
.acquire_dev = __cam_fd_ctx_acquire_dev_in_available,
|
.acquire_dev = __cam_fd_ctx_acquire_dev_in_available,
|
||||||
|
.shutdown_dev = __cam_fd_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = NULL,
|
.irq_ops = NULL,
|
||||||
@@ -192,18 +206,25 @@ static struct cam_ctx_ops
|
|||||||
.release_dev = __cam_fd_ctx_release_dev_in_acquired,
|
.release_dev = __cam_fd_ctx_release_dev_in_acquired,
|
||||||
.config_dev = __cam_fd_ctx_config_dev_in_acquired,
|
.config_dev = __cam_fd_ctx_config_dev_in_acquired,
|
||||||
.start_dev = __cam_fd_ctx_start_dev_in_acquired,
|
.start_dev = __cam_fd_ctx_start_dev_in_acquired,
|
||||||
|
.shutdown_dev = __cam_fd_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = NULL,
|
.irq_ops = NULL,
|
||||||
},
|
},
|
||||||
/* Ready */
|
/* Ready */
|
||||||
{
|
{
|
||||||
.ioctl_ops = { },
|
.ioctl_ops = {
|
||||||
|
.shutdown_dev = __cam_fd_shutdown_dev,
|
||||||
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = NULL,
|
.irq_ops = NULL,
|
||||||
},
|
},
|
||||||
/* Flushed */
|
/* Flushed */
|
||||||
{},
|
{
|
||||||
|
.ioctl_ops = {
|
||||||
|
.shutdown_dev = __cam_fd_shutdown_dev,
|
||||||
|
},
|
||||||
|
},
|
||||||
/* Activated */
|
/* Activated */
|
||||||
{
|
{
|
||||||
.ioctl_ops = {
|
.ioctl_ops = {
|
||||||
@@ -212,6 +233,7 @@ static struct cam_ctx_ops
|
|||||||
.config_dev = __cam_fd_ctx_config_dev_in_activated,
|
.config_dev = __cam_fd_ctx_config_dev_in_activated,
|
||||||
.flush_dev = __cam_fd_ctx_flush_dev_in_activated,
|
.flush_dev = __cam_fd_ctx_flush_dev_in_activated,
|
||||||
.dump_dev = __cam_fd_ctx_dump_dev_in_activated,
|
.dump_dev = __cam_fd_ctx_dump_dev_in_activated,
|
||||||
|
.shutdown_dev = __cam_fd_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = __cam_fd_ctx_handle_irq_in_activated,
|
.irq_ops = __cam_fd_ctx_handle_irq_in_activated,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2018, 2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CAM_FD_CONTEXT_H_
|
#ifndef _CAM_FD_CONTEXT_H_
|
||||||
@@ -27,4 +27,15 @@ int cam_fd_context_init(struct cam_fd_context *fd_ctx,
|
|||||||
uint32_t ctx_id);
|
uint32_t ctx_id);
|
||||||
int cam_fd_context_deinit(struct cam_fd_context *ctx);
|
int cam_fd_context_deinit(struct cam_fd_context *ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cam_fd_dev_close_internal()
|
||||||
|
*
|
||||||
|
* @brief: Close function for the fd dev
|
||||||
|
*
|
||||||
|
* @sd: Pointer to struct v4l2_subdev
|
||||||
|
* @fh: Pointer to struct v4l2_subdev_fh
|
||||||
|
*/
|
||||||
|
int cam_fd_dev_close_internal(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh);
|
||||||
|
|
||||||
#endif /* _CAM_FD_CONTEXT_H_ */
|
#endif /* _CAM_FD_CONTEXT_H_ */
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
@@ -57,7 +57,7 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cam_fd_dev_close(struct v4l2_subdev *sd,
|
static int cam_fd_dev_close_internal(struct v4l2_subdev *sd,
|
||||||
struct v4l2_subdev_fh *fh)
|
struct v4l2_subdev_fh *fh)
|
||||||
{
|
{
|
||||||
struct cam_fd_dev *fd_dev = &g_fd_dev;
|
struct cam_fd_dev *fd_dev = &g_fd_dev;
|
||||||
@@ -69,6 +69,11 @@ static int cam_fd_dev_close(struct v4l2_subdev *sd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&fd_dev->lock);
|
mutex_lock(&fd_dev->lock);
|
||||||
|
if (fd_dev->open_cnt == 0) {
|
||||||
|
CAM_WARN(CAM_FD, "device already closed");
|
||||||
|
mutex_unlock(&fd_dev->lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
fd_dev->open_cnt--;
|
fd_dev->open_cnt--;
|
||||||
CAM_DBG(CAM_FD, "FD Subdev open count %d", fd_dev->open_cnt);
|
CAM_DBG(CAM_FD, "FD Subdev open count %d", fd_dev->open_cnt);
|
||||||
mutex_unlock(&fd_dev->lock);
|
mutex_unlock(&fd_dev->lock);
|
||||||
@@ -83,6 +88,19 @@ static int cam_fd_dev_close(struct v4l2_subdev *sd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cam_fd_dev_close(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
bool crm_active = cam_req_mgr_is_open(CAM_FD);
|
||||||
|
|
||||||
|
if (crm_active) {
|
||||||
|
CAM_DBG(CAM_FD, "CRM is ACTIVE, close should be from CRM");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cam_fd_dev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct v4l2_subdev_internal_ops cam_fd_subdev_internal_ops = {
|
static const struct v4l2_subdev_internal_ops cam_fd_subdev_internal_ops = {
|
||||||
.open = cam_fd_dev_open,
|
.open = cam_fd_dev_open,
|
||||||
.close = cam_fd_dev_close,
|
.close = cam_fd_dev_close,
|
||||||
@@ -98,6 +116,7 @@ static int cam_fd_dev_component_bind(struct device *dev,
|
|||||||
struct platform_device *pdev = to_platform_device(dev);
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
|
|
||||||
g_fd_dev.sd.internal_ops = &cam_fd_subdev_internal_ops;
|
g_fd_dev.sd.internal_ops = &cam_fd_subdev_internal_ops;
|
||||||
|
g_fd_dev.sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||||
|
|
||||||
/* Initialize the v4l2 subdevice first. (create cam_node) */
|
/* Initialize the v4l2 subdevice first. (create cam_node) */
|
||||||
rc = cam_subdev_probe(&g_fd_dev.sd, pdev, CAM_FD_DEV_NAME,
|
rc = cam_subdev_probe(&g_fd_dev.sd, pdev, CAM_FD_DEV_NAME,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
@@ -221,6 +221,12 @@ static int __cam_icp_handle_buf_done_in_ready(void *ctx,
|
|||||||
return cam_context_buf_done_from_hw(ctx, done, evt_id);
|
return cam_context_buf_done_from_hw(ctx, done, evt_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __cam_icp_shutdown_dev(
|
||||||
|
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
return cam_icp_subdev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
static struct cam_ctx_ops
|
static struct cam_ctx_ops
|
||||||
cam_icp_ctx_state_machine[CAM_CTX_STATE_MAX] = {
|
cam_icp_ctx_state_machine[CAM_CTX_STATE_MAX] = {
|
||||||
/* Uninit */
|
/* Uninit */
|
||||||
@@ -233,6 +239,7 @@ static struct cam_ctx_ops
|
|||||||
{
|
{
|
||||||
.ioctl_ops = {
|
.ioctl_ops = {
|
||||||
.acquire_dev = __cam_icp_acquire_dev_in_available,
|
.acquire_dev = __cam_icp_acquire_dev_in_available,
|
||||||
|
.shutdown_dev = __cam_icp_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = NULL,
|
.irq_ops = NULL,
|
||||||
@@ -245,6 +252,7 @@ static struct cam_ctx_ops
|
|||||||
.config_dev = __cam_icp_config_dev_in_ready,
|
.config_dev = __cam_icp_config_dev_in_ready,
|
||||||
.flush_dev = __cam_icp_flush_dev_in_ready,
|
.flush_dev = __cam_icp_flush_dev_in_ready,
|
||||||
.dump_dev = __cam_icp_dump_dev_in_ready,
|
.dump_dev = __cam_icp_dump_dev_in_ready,
|
||||||
|
.shutdown_dev = __cam_icp_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = __cam_icp_handle_buf_done_in_ready,
|
.irq_ops = __cam_icp_handle_buf_done_in_ready,
|
||||||
@@ -258,16 +266,23 @@ static struct cam_ctx_ops
|
|||||||
.config_dev = __cam_icp_config_dev_in_ready,
|
.config_dev = __cam_icp_config_dev_in_ready,
|
||||||
.flush_dev = __cam_icp_flush_dev_in_ready,
|
.flush_dev = __cam_icp_flush_dev_in_ready,
|
||||||
.dump_dev = __cam_icp_dump_dev_in_ready,
|
.dump_dev = __cam_icp_dump_dev_in_ready,
|
||||||
|
.shutdown_dev = __cam_icp_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = __cam_icp_handle_buf_done_in_ready,
|
.irq_ops = __cam_icp_handle_buf_done_in_ready,
|
||||||
.pagefault_ops = cam_icp_context_dump_active_request,
|
.pagefault_ops = cam_icp_context_dump_active_request,
|
||||||
},
|
},
|
||||||
/* Flushed */
|
/* Flushed */
|
||||||
{},
|
{
|
||||||
|
.ioctl_ops = {
|
||||||
|
.shutdown_dev = __cam_icp_shutdown_dev,
|
||||||
|
},
|
||||||
|
},
|
||||||
/* Activated */
|
/* Activated */
|
||||||
{
|
{
|
||||||
.ioctl_ops = {},
|
.ioctl_ops = {
|
||||||
|
.shutdown_dev = __cam_icp_shutdown_dev,
|
||||||
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = NULL,
|
.irq_ops = NULL,
|
||||||
.pagefault_ops = cam_icp_context_dump_active_request,
|
.pagefault_ops = cam_icp_context_dump_active_request,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CAM_ICP_CONTEXT_H_
|
#ifndef _CAM_ICP_CONTEXT_H_
|
||||||
@@ -39,4 +39,12 @@ int cam_icp_context_init(struct cam_icp_context *ctx,
|
|||||||
*/
|
*/
|
||||||
int cam_icp_context_deinit(struct cam_icp_context *ctx);
|
int cam_icp_context_deinit(struct cam_icp_context *ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cam_icp_subdev_close_internal() - Close function for the icp dev
|
||||||
|
* @sd: Pointer to struct v4l2_subdev
|
||||||
|
* @fh: Pointer to struct v4l2_subdev_fh
|
||||||
|
*/
|
||||||
|
int cam_icp_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh);
|
||||||
|
|
||||||
#endif /* _CAM_ICP_CONTEXT_H_ */
|
#endif /* _CAM_ICP_CONTEXT_H_ */
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
@@ -98,7 +98,7 @@ end:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cam_icp_subdev_close(struct v4l2_subdev *sd,
|
int cam_icp_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
struct v4l2_subdev_fh *fh)
|
struct v4l2_subdev_fh *fh)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -107,9 +107,8 @@ static int cam_icp_subdev_close(struct v4l2_subdev *sd,
|
|||||||
|
|
||||||
mutex_lock(&g_icp_dev.icp_lock);
|
mutex_lock(&g_icp_dev.icp_lock);
|
||||||
if (g_icp_dev.open_cnt <= 0) {
|
if (g_icp_dev.open_cnt <= 0) {
|
||||||
CAM_DBG(CAM_ICP, "ICP subdev is already closed");
|
CAM_WARN(CAM_ICP, "ICP subdev is already closed");
|
||||||
rc = -EINVAL;
|
return 0;
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
g_icp_dev.open_cnt--;
|
g_icp_dev.open_cnt--;
|
||||||
if (!node) {
|
if (!node) {
|
||||||
@@ -133,7 +132,20 @@ static int cam_icp_subdev_close(struct v4l2_subdev *sd,
|
|||||||
|
|
||||||
end:
|
end:
|
||||||
mutex_unlock(&g_icp_dev.icp_lock);
|
mutex_unlock(&g_icp_dev.icp_lock);
|
||||||
return 0;
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cam_icp_subdev_close(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
bool crm_active = cam_req_mgr_is_open(CAM_ICP);
|
||||||
|
|
||||||
|
if (crm_active) {
|
||||||
|
CAM_DBG(CAM_ICP, "CRM is ACTIVE, close should be from CRM");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cam_icp_subdev_close_internal(sd, fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct v4l2_subdev_internal_ops cam_icp_subdev_internal_ops = {
|
const struct v4l2_subdev_internal_ops cam_icp_subdev_internal_ops = {
|
||||||
@@ -157,6 +169,7 @@ static int cam_icp_component_bind(struct device *dev,
|
|||||||
|
|
||||||
g_icp_dev.sd.pdev = pdev;
|
g_icp_dev.sd.pdev = pdev;
|
||||||
g_icp_dev.sd.internal_ops = &cam_icp_subdev_internal_ops;
|
g_icp_dev.sd.internal_ops = &cam_icp_subdev_internal_ops;
|
||||||
|
g_icp_dev.sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||||
rc = cam_subdev_probe(&g_icp_dev.sd, pdev, CAM_ICP_DEV_NAME,
|
rc = cam_subdev_probe(&g_icp_dev.sd, pdev, CAM_ICP_DEV_NAME,
|
||||||
CAM_ICP_DEVICE_TYPE);
|
CAM_ICP_DEVICE_TYPE);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@@ -6405,6 +6405,12 @@ static int __cam_isp_ctx_handle_irq_in_activated(void *context,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __cam_isp_shutdown_dev(
|
||||||
|
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
return cam_isp_subdev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
/* top state machine */
|
/* top state machine */
|
||||||
static struct cam_ctx_ops
|
static struct cam_ctx_ops
|
||||||
cam_isp_ctx_top_state_machine[CAM_CTX_STATE_MAX] = {
|
cam_isp_ctx_top_state_machine[CAM_CTX_STATE_MAX] = {
|
||||||
@@ -6418,6 +6424,7 @@ static struct cam_ctx_ops
|
|||||||
{
|
{
|
||||||
.ioctl_ops = {
|
.ioctl_ops = {
|
||||||
.acquire_dev = __cam_isp_ctx_acquire_dev_in_available,
|
.acquire_dev = __cam_isp_ctx_acquire_dev_in_available,
|
||||||
|
.shutdown_dev = __cam_isp_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = NULL,
|
.irq_ops = NULL,
|
||||||
@@ -6429,6 +6436,7 @@ static struct cam_ctx_ops
|
|||||||
.release_dev = __cam_isp_ctx_release_dev_in_top_state,
|
.release_dev = __cam_isp_ctx_release_dev_in_top_state,
|
||||||
.config_dev = __cam_isp_ctx_config_dev_in_acquired,
|
.config_dev = __cam_isp_ctx_config_dev_in_acquired,
|
||||||
.release_hw = __cam_isp_ctx_release_hw_in_top_state,
|
.release_hw = __cam_isp_ctx_release_hw_in_top_state,
|
||||||
|
.shutdown_dev = __cam_isp_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {
|
.crm_ops = {
|
||||||
.link = __cam_isp_ctx_link_in_acquired,
|
.link = __cam_isp_ctx_link_in_acquired,
|
||||||
@@ -6448,6 +6456,7 @@ static struct cam_ctx_ops
|
|||||||
.release_dev = __cam_isp_ctx_release_dev_in_top_state,
|
.release_dev = __cam_isp_ctx_release_dev_in_top_state,
|
||||||
.config_dev = __cam_isp_ctx_config_dev_in_top_state,
|
.config_dev = __cam_isp_ctx_config_dev_in_top_state,
|
||||||
.release_hw = __cam_isp_ctx_release_hw_in_top_state,
|
.release_hw = __cam_isp_ctx_release_hw_in_top_state,
|
||||||
|
.shutdown_dev = __cam_isp_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {
|
.crm_ops = {
|
||||||
.unlink = __cam_isp_ctx_unlink_in_ready,
|
.unlink = __cam_isp_ctx_unlink_in_ready,
|
||||||
@@ -6465,6 +6474,7 @@ static struct cam_ctx_ops
|
|||||||
.release_dev = __cam_isp_ctx_release_dev_in_activated,
|
.release_dev = __cam_isp_ctx_release_dev_in_activated,
|
||||||
.config_dev = __cam_isp_ctx_config_dev_in_flushed,
|
.config_dev = __cam_isp_ctx_config_dev_in_flushed,
|
||||||
.release_hw = __cam_isp_ctx_release_hw_in_activated,
|
.release_hw = __cam_isp_ctx_release_hw_in_activated,
|
||||||
|
.shutdown_dev = __cam_isp_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {
|
.crm_ops = {
|
||||||
.unlink = __cam_isp_ctx_unlink_in_ready,
|
.unlink = __cam_isp_ctx_unlink_in_ready,
|
||||||
@@ -6481,6 +6491,7 @@ static struct cam_ctx_ops
|
|||||||
.release_dev = __cam_isp_ctx_release_dev_in_activated,
|
.release_dev = __cam_isp_ctx_release_dev_in_activated,
|
||||||
.config_dev = __cam_isp_ctx_config_dev_in_top_state,
|
.config_dev = __cam_isp_ctx_config_dev_in_top_state,
|
||||||
.release_hw = __cam_isp_ctx_release_hw_in_activated,
|
.release_hw = __cam_isp_ctx_release_hw_in_activated,
|
||||||
|
.shutdown_dev = __cam_isp_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {
|
.crm_ops = {
|
||||||
.unlink = __cam_isp_ctx_unlink_in_activated,
|
.unlink = __cam_isp_ctx_unlink_in_activated,
|
||||||
|
@@ -372,5 +372,16 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
|
|||||||
*/
|
*/
|
||||||
int cam_isp_context_deinit(struct cam_isp_context *ctx);
|
int cam_isp_context_deinit(struct cam_isp_context *ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cam_isp_subdev_close_internal()
|
||||||
|
*
|
||||||
|
* @brief: Close function for the isp dev
|
||||||
|
*
|
||||||
|
* @sd: Pointer to struct v4l2_subdev
|
||||||
|
* @fh: Pointer to struct v4l2_subdev_fh
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int cam_isp_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh);
|
||||||
|
|
||||||
#endif /* __CAM_ISP_CONTEXT_H__ */
|
#endif /* __CAM_ISP_CONTEXT_H__ */
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
@@ -55,7 +55,7 @@ static int cam_isp_subdev_open(struct v4l2_subdev *sd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cam_isp_subdev_close(struct v4l2_subdev *sd,
|
int cam_isp_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
struct v4l2_subdev_fh *fh)
|
struct v4l2_subdev_fh *fh)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -83,6 +83,18 @@ end:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cam_isp_subdev_close(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
bool crm_active = cam_req_mgr_is_open(CAM_ISP);
|
||||||
|
|
||||||
|
if (crm_active) {
|
||||||
|
CAM_DBG(CAM_ISP, "CRM is ACTIVE, close should be from CRM");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return cam_isp_subdev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct v4l2_subdev_internal_ops cam_isp_subdev_internal_ops = {
|
static const struct v4l2_subdev_internal_ops cam_isp_subdev_internal_ops = {
|
||||||
.close = cam_isp_subdev_close,
|
.close = cam_isp_subdev_close,
|
||||||
.open = cam_isp_subdev_open,
|
.open = cam_isp_subdev_open,
|
||||||
@@ -104,6 +116,7 @@ static int cam_isp_dev_component_bind(struct device *dev,
|
|||||||
(const char **)&compat_str);
|
(const char **)&compat_str);
|
||||||
|
|
||||||
g_isp_dev.sd.internal_ops = &cam_isp_subdev_internal_ops;
|
g_isp_dev.sd.internal_ops = &cam_isp_subdev_internal_ops;
|
||||||
|
g_isp_dev.sd.close_seq_prior = CAM_SD_CLOSE_HIGH_PRIORITY;
|
||||||
/* Initialize the v4l2 subdevice first. (create cam_node) */
|
/* Initialize the v4l2 subdevice first. (create cam_node) */
|
||||||
if (strnstr(compat_str, "ife", strlen(compat_str))) {
|
if (strnstr(compat_str, "ife", strlen(compat_str))) {
|
||||||
rc = cam_subdev_probe(&g_isp_dev.sd, pdev, CAM_ISP_DEV_NAME,
|
rc = cam_subdev_probe(&g_isp_dev.sd, pdev, CAM_ISP_DEV_NAME,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
@@ -135,6 +135,12 @@ static int __cam_jpeg_ctx_stop_dev_in_acquired(struct cam_context *ctx,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __cam_jpeg_shutdown_dev(
|
||||||
|
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
return cam_jpeg_subdev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
/* top state machine */
|
/* top state machine */
|
||||||
static struct cam_ctx_ops
|
static struct cam_ctx_ops
|
||||||
cam_jpeg_ctx_state_machine[CAM_CTX_STATE_MAX] = {
|
cam_jpeg_ctx_state_machine[CAM_CTX_STATE_MAX] = {
|
||||||
@@ -148,6 +154,7 @@ static struct cam_ctx_ops
|
|||||||
{
|
{
|
||||||
.ioctl_ops = {
|
.ioctl_ops = {
|
||||||
.acquire_dev = __cam_jpeg_ctx_acquire_dev_in_available,
|
.acquire_dev = __cam_jpeg_ctx_acquire_dev_in_available,
|
||||||
|
.shutdown_dev = __cam_jpeg_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = { },
|
.crm_ops = { },
|
||||||
.irq_ops = NULL,
|
.irq_ops = NULL,
|
||||||
@@ -160,11 +167,30 @@ static struct cam_ctx_ops
|
|||||||
.stop_dev = __cam_jpeg_ctx_stop_dev_in_acquired,
|
.stop_dev = __cam_jpeg_ctx_stop_dev_in_acquired,
|
||||||
.flush_dev = __cam_jpeg_ctx_flush_dev_in_acquired,
|
.flush_dev = __cam_jpeg_ctx_flush_dev_in_acquired,
|
||||||
.dump_dev = __cam_jpeg_ctx_dump_dev_in_acquired,
|
.dump_dev = __cam_jpeg_ctx_dump_dev_in_acquired,
|
||||||
|
.shutdown_dev = __cam_jpeg_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = { },
|
.crm_ops = { },
|
||||||
.irq_ops = __cam_jpeg_ctx_handle_buf_done_in_acquired,
|
.irq_ops = __cam_jpeg_ctx_handle_buf_done_in_acquired,
|
||||||
.pagefault_ops = cam_jpeg_context_dump_active_request,
|
.pagefault_ops = cam_jpeg_context_dump_active_request,
|
||||||
},
|
},
|
||||||
|
/* Ready */
|
||||||
|
{
|
||||||
|
.ioctl_ops = {
|
||||||
|
.shutdown_dev = __cam_jpeg_shutdown_dev,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* Flushed */
|
||||||
|
{
|
||||||
|
.ioctl_ops = {
|
||||||
|
.shutdown_dev = __cam_jpeg_shutdown_dev,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* Activated */
|
||||||
|
{
|
||||||
|
.ioctl_ops = {
|
||||||
|
.shutdown_dev = __cam_jpeg_shutdown_dev,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
int cam_jpeg_context_init(struct cam_jpeg_context *ctx,
|
int cam_jpeg_context_init(struct cam_jpeg_context *ctx,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2018, 2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CAM_JPEG_CONTEXT_H_
|
#ifndef _CAM_JPEG_CONTEXT_H_
|
||||||
@@ -64,4 +64,16 @@ int cam_jpeg_context_init(struct cam_jpeg_context *ctx,
|
|||||||
*/
|
*/
|
||||||
int cam_jpeg_context_deinit(struct cam_jpeg_context *ctx);
|
int cam_jpeg_context_deinit(struct cam_jpeg_context *ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cam_jpeg_subdev_close_internal()
|
||||||
|
*
|
||||||
|
* @brief: Close function for the jpeg dev
|
||||||
|
*
|
||||||
|
* @sd: Pointer to struct v4l2_subdev
|
||||||
|
* @fh: Pointer to struct v4l2_subdev_fh
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int cam_jpeg_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh);
|
||||||
|
|
||||||
#endif /* __CAM_JPEG_CONTEXT_H__ */
|
#endif /* __CAM_JPEG_CONTEXT_H__ */
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
@@ -56,13 +56,12 @@ static int cam_jpeg_subdev_open(struct v4l2_subdev *sd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cam_jpeg_subdev_close(struct v4l2_subdev *sd,
|
int cam_jpeg_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
struct v4l2_subdev_fh *fh)
|
struct v4l2_subdev_fh *fh)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct cam_node *node = v4l2_get_subdevdata(sd);
|
struct cam_node *node = v4l2_get_subdevdata(sd);
|
||||||
|
|
||||||
|
|
||||||
mutex_lock(&g_jpeg_dev.jpeg_mutex);
|
mutex_lock(&g_jpeg_dev.jpeg_mutex);
|
||||||
if (g_jpeg_dev.open_cnt <= 0) {
|
if (g_jpeg_dev.open_cnt <= 0) {
|
||||||
CAM_DBG(CAM_JPEG, "JPEG subdev is already closed");
|
CAM_DBG(CAM_JPEG, "JPEG subdev is already closed");
|
||||||
@@ -86,6 +85,18 @@ end:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cam_jpeg_subdev_close(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
bool crm_active = cam_req_mgr_is_open(CAM_JPEG);
|
||||||
|
|
||||||
|
if (crm_active) {
|
||||||
|
CAM_DBG(CAM_JPEG, "CRM is ACTIVE, close should be from CRM");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return cam_jpeg_subdev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct v4l2_subdev_internal_ops cam_jpeg_subdev_internal_ops = {
|
static const struct v4l2_subdev_internal_ops cam_jpeg_subdev_internal_ops = {
|
||||||
.close = cam_jpeg_subdev_close,
|
.close = cam_jpeg_subdev_close,
|
||||||
.open = cam_jpeg_subdev_open,
|
.open = cam_jpeg_subdev_open,
|
||||||
@@ -102,6 +113,7 @@ static int cam_jpeg_dev_component_bind(struct device *dev,
|
|||||||
struct platform_device *pdev = to_platform_device(dev);
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
|
|
||||||
g_jpeg_dev.sd.internal_ops = &cam_jpeg_subdev_internal_ops;
|
g_jpeg_dev.sd.internal_ops = &cam_jpeg_subdev_internal_ops;
|
||||||
|
g_jpeg_dev.sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||||
rc = cam_subdev_probe(&g_jpeg_dev.sd, pdev, CAM_JPEG_DEV_NAME,
|
rc = cam_subdev_probe(&g_jpeg_dev.sd, pdev, CAM_JPEG_DEV_NAME,
|
||||||
CAM_JPEG_DEVICE_TYPE);
|
CAM_JPEG_DEVICE_TYPE);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
@@ -172,6 +172,12 @@ static int __cam_lrme_ctx_handle_irq_in_activated(void *context,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __cam_lrme_shutdown_dev(
|
||||||
|
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
return cam_lrme_dev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
/* top state machine */
|
/* top state machine */
|
||||||
static struct cam_ctx_ops
|
static struct cam_ctx_ops
|
||||||
cam_lrme_ctx_state_machine[CAM_CTX_STATE_MAX] = {
|
cam_lrme_ctx_state_machine[CAM_CTX_STATE_MAX] = {
|
||||||
@@ -185,6 +191,7 @@ static struct cam_ctx_ops
|
|||||||
{
|
{
|
||||||
.ioctl_ops = {
|
.ioctl_ops = {
|
||||||
.acquire_dev = __cam_lrme_ctx_acquire_dev_in_available,
|
.acquire_dev = __cam_lrme_ctx_acquire_dev_in_available,
|
||||||
|
.shutdown_dev = __cam_lrme_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = NULL,
|
.irq_ops = NULL,
|
||||||
@@ -195,18 +202,25 @@ static struct cam_ctx_ops
|
|||||||
.config_dev = __cam_lrme_ctx_config_dev_in_activated,
|
.config_dev = __cam_lrme_ctx_config_dev_in_activated,
|
||||||
.release_dev = __cam_lrme_ctx_release_dev_in_acquired,
|
.release_dev = __cam_lrme_ctx_release_dev_in_acquired,
|
||||||
.start_dev = __cam_lrme_ctx_start_dev_in_acquired,
|
.start_dev = __cam_lrme_ctx_start_dev_in_acquired,
|
||||||
|
.shutdown_dev = __cam_lrme_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = NULL,
|
.irq_ops = NULL,
|
||||||
},
|
},
|
||||||
/* Ready */
|
/* Ready */
|
||||||
{
|
{
|
||||||
.ioctl_ops = {},
|
.ioctl_ops = {
|
||||||
|
.shutdown_dev = __cam_lrme_shutdown_dev,
|
||||||
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = NULL,
|
.irq_ops = NULL,
|
||||||
},
|
},
|
||||||
/* Flushed */
|
/* Flushed */
|
||||||
{},
|
{
|
||||||
|
.ioctl_ops = {
|
||||||
|
.shutdown_dev = __cam_lrme_shutdown_dev,
|
||||||
|
},
|
||||||
|
},
|
||||||
/* Activate */
|
/* Activate */
|
||||||
{
|
{
|
||||||
.ioctl_ops = {
|
.ioctl_ops = {
|
||||||
@@ -215,6 +229,7 @@ static struct cam_ctx_ops
|
|||||||
.stop_dev = __cam_lrme_ctx_stop_dev_in_activated,
|
.stop_dev = __cam_lrme_ctx_stop_dev_in_activated,
|
||||||
.flush_dev = __cam_lrme_ctx_flush_dev_in_activated,
|
.flush_dev = __cam_lrme_ctx_flush_dev_in_activated,
|
||||||
.dump_dev = __cam_lrme_ctx_dump_dev_in_activated,
|
.dump_dev = __cam_lrme_ctx_dump_dev_in_activated,
|
||||||
|
.shutdown_dev = __cam_lrme_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = __cam_lrme_ctx_handle_irq_in_activated,
|
.irq_ops = __cam_lrme_ctx_handle_irq_in_activated,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CAM_LRME_CONTEXT_H_
|
#ifndef _CAM_LRME_CONTEXT_H_
|
||||||
@@ -30,4 +30,16 @@ int cam_lrme_context_init(struct cam_lrme_context *lrme_ctx,
|
|||||||
uint32_t index);
|
uint32_t index);
|
||||||
int cam_lrme_context_deinit(struct cam_lrme_context *lrme_ctx);
|
int cam_lrme_context_deinit(struct cam_lrme_context *lrme_ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cam_lrme_dev_close_internal()
|
||||||
|
*
|
||||||
|
* @brief: Close function for the jpeg dev
|
||||||
|
*
|
||||||
|
* @sd: Pointer to struct v4l2_subdev
|
||||||
|
* @fh: Pointer to struct v4l2_subdev_fh
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int cam_lrme_dev_close_internal(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh);
|
||||||
|
|
||||||
#endif /* _CAM_LRME_CONTEXT_H_ */
|
#endif /* _CAM_LRME_CONTEXT_H_ */
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
@@ -72,7 +72,7 @@ static int cam_lrme_dev_open(struct v4l2_subdev *sd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cam_lrme_dev_close(struct v4l2_subdev *sd,
|
int cam_lrme_dev_close_internal(struct v4l2_subdev *sd,
|
||||||
struct v4l2_subdev_fh *fh)
|
struct v4l2_subdev_fh *fh)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -106,6 +106,18 @@ end:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cam_lrme_dev_close(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
bool crm_active = cam_req_mgr_is_open(CAM_LRME);
|
||||||
|
|
||||||
|
if (crm_active) {
|
||||||
|
CAM_DBG(CAM_LRME, "CRM is ACTIVE, close should be from CRM");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return cam_lrme_dev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct v4l2_subdev_internal_ops cam_lrme_subdev_internal_ops = {
|
static const struct v4l2_subdev_internal_ops cam_lrme_subdev_internal_ops = {
|
||||||
.open = cam_lrme_dev_open,
|
.open = cam_lrme_dev_open,
|
||||||
.close = cam_lrme_dev_close,
|
.close = cam_lrme_dev_close,
|
||||||
@@ -126,6 +138,7 @@ static int cam_lrme_component_bind(struct device *dev,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
g_lrme_dev->sd.internal_ops = &cam_lrme_subdev_internal_ops;
|
g_lrme_dev->sd.internal_ops = &cam_lrme_subdev_internal_ops;
|
||||||
|
g_lrme_dev->sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||||
|
|
||||||
mutex_init(&g_lrme_dev->lock);
|
mutex_init(&g_lrme_dev->lock);
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
@@ -195,6 +195,12 @@ static int __cam_ope_handle_buf_done_in_ready(void *ctx,
|
|||||||
return cam_context_buf_done_from_hw(ctx, done, evt_id);
|
return cam_context_buf_done_from_hw(ctx, done, evt_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __cam_ope_shutdown_dev(
|
||||||
|
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
return cam_ope_subdev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
static struct cam_ctx_ops
|
static struct cam_ctx_ops
|
||||||
cam_ope_ctx_state_machine[CAM_CTX_STATE_MAX] = {
|
cam_ope_ctx_state_machine[CAM_CTX_STATE_MAX] = {
|
||||||
/* Uninit */
|
/* Uninit */
|
||||||
@@ -207,6 +213,7 @@ static struct cam_ctx_ops
|
|||||||
{
|
{
|
||||||
.ioctl_ops = {
|
.ioctl_ops = {
|
||||||
.acquire_dev = __cam_ope_acquire_dev_in_available,
|
.acquire_dev = __cam_ope_acquire_dev_in_available,
|
||||||
|
.shutdown_dev = __cam_ope_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = NULL,
|
.irq_ops = NULL,
|
||||||
@@ -219,6 +226,7 @@ static struct cam_ctx_ops
|
|||||||
.config_dev = __cam_ope_config_dev_in_ready,
|
.config_dev = __cam_ope_config_dev_in_ready,
|
||||||
.flush_dev = __cam_ope_flush_dev_in_ready,
|
.flush_dev = __cam_ope_flush_dev_in_ready,
|
||||||
.dump_dev = __cam_ope_dump_dev_in_ready,
|
.dump_dev = __cam_ope_dump_dev_in_ready,
|
||||||
|
.shutdown_dev = __cam_ope_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = __cam_ope_handle_buf_done_in_ready,
|
.irq_ops = __cam_ope_handle_buf_done_in_ready,
|
||||||
@@ -232,14 +240,23 @@ static struct cam_ctx_ops
|
|||||||
.config_dev = __cam_ope_config_dev_in_ready,
|
.config_dev = __cam_ope_config_dev_in_ready,
|
||||||
.flush_dev = __cam_ope_flush_dev_in_ready,
|
.flush_dev = __cam_ope_flush_dev_in_ready,
|
||||||
.dump_dev = __cam_ope_dump_dev_in_ready,
|
.dump_dev = __cam_ope_dump_dev_in_ready,
|
||||||
|
.shutdown_dev = __cam_ope_shutdown_dev,
|
||||||
},
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = __cam_ope_handle_buf_done_in_ready,
|
.irq_ops = __cam_ope_handle_buf_done_in_ready,
|
||||||
.pagefault_ops = cam_ope_context_dump_active_request,
|
.pagefault_ops = cam_ope_context_dump_active_request,
|
||||||
},
|
},
|
||||||
|
/* Flushed */
|
||||||
|
{
|
||||||
|
.ioctl_ops = {
|
||||||
|
.shutdown_dev = __cam_ope_shutdown_dev,
|
||||||
|
},
|
||||||
|
},
|
||||||
/* Activated */
|
/* Activated */
|
||||||
{
|
{
|
||||||
.ioctl_ops = {},
|
.ioctl_ops = {
|
||||||
|
.shutdown_dev = __cam_ope_shutdown_dev,
|
||||||
|
},
|
||||||
.crm_ops = {},
|
.crm_ops = {},
|
||||||
.irq_ops = NULL,
|
.irq_ops = NULL,
|
||||||
.pagefault_ops = cam_ope_context_dump_active_request,
|
.pagefault_ops = cam_ope_context_dump_active_request,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CAM_OPE_CONTEXT_H_
|
#ifndef _CAM_OPE_CONTEXT_H_
|
||||||
@@ -41,4 +41,12 @@ int cam_ope_context_init(struct cam_ope_context *ctx,
|
|||||||
*/
|
*/
|
||||||
int cam_ope_context_deinit(struct cam_ope_context *ctx);
|
int cam_ope_context_deinit(struct cam_ope_context *ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cam_ope_subdev_close_internal() - Close function for the icp dev
|
||||||
|
* @sd: Pointer to struct v4l2_subdev
|
||||||
|
* @fh: Pointer to struct v4l2_subdev_fh
|
||||||
|
*/
|
||||||
|
int cam_ope_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh);
|
||||||
|
|
||||||
#endif /* _CAM_OPE_CONTEXT_H_ */
|
#endif /* _CAM_OPE_CONTEXT_H_ */
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
@@ -95,7 +95,7 @@ end:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cam_ope_subdev_close(struct v4l2_subdev *sd,
|
int cam_ope_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
struct v4l2_subdev_fh *fh)
|
struct v4l2_subdev_fh *fh)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -134,6 +134,19 @@ end:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cam_ope_subdev_close(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
bool crm_active = cam_req_mgr_is_open(CAM_OPE);
|
||||||
|
|
||||||
|
if (crm_active) {
|
||||||
|
CAM_DBG(CAM_OPE, "CRM is ACTIVE, close should be from CRM");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cam_ope_subdev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
const struct v4l2_subdev_internal_ops cam_ope_subdev_internal_ops = {
|
const struct v4l2_subdev_internal_ops cam_ope_subdev_internal_ops = {
|
||||||
.open = cam_ope_subdev_open,
|
.open = cam_ope_subdev_open,
|
||||||
.close = cam_ope_subdev_close,
|
.close = cam_ope_subdev_close,
|
||||||
@@ -156,6 +169,7 @@ static int cam_ope_subdev_component_bind(struct device *dev,
|
|||||||
|
|
||||||
g_ope_dev.sd.pdev = pdev;
|
g_ope_dev.sd.pdev = pdev;
|
||||||
g_ope_dev.sd.internal_ops = &cam_ope_subdev_internal_ops;
|
g_ope_dev.sd.internal_ops = &cam_ope_subdev_internal_ops;
|
||||||
|
g_ope_dev.sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||||
rc = cam_subdev_probe(&g_ope_dev.sd, pdev, OPE_DEV_NAME,
|
rc = cam_subdev_probe(&g_ope_dev.sd, pdev, OPE_DEV_NAME,
|
||||||
CAM_OPE_DEVICE_TYPE);
|
CAM_OPE_DEVICE_TYPE);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include <media/v4l2-ioctl.h>
|
#include <media/v4l2-ioctl.h>
|
||||||
#include <media/cam_req_mgr.h>
|
#include <media/cam_req_mgr.h>
|
||||||
#include <media/cam_defs.h>
|
#include <media/cam_defs.h>
|
||||||
|
#include <linux/list_sort.h>
|
||||||
|
|
||||||
#include "cam_req_mgr_dev.h"
|
#include "cam_req_mgr_dev.h"
|
||||||
#include "cam_req_mgr_util.h"
|
#include "cam_req_mgr_util.h"
|
||||||
@@ -32,6 +33,7 @@
|
|||||||
|
|
||||||
static struct cam_req_mgr_device g_dev;
|
static struct cam_req_mgr_device g_dev;
|
||||||
struct kmem_cache *g_cam_req_mgr_timer_cachep;
|
struct kmem_cache *g_cam_req_mgr_timer_cachep;
|
||||||
|
static struct list_head cam_req_mgr_ordered_sd_list;
|
||||||
|
|
||||||
static struct device_attribute camera_debug_sysfs_attr =
|
static struct device_attribute camera_debug_sysfs_attr =
|
||||||
__ATTR(debug_node, 0600, NULL, cam_debug_sysfs_node_store);
|
__ATTR(debug_node, 0600, NULL, cam_debug_sysfs_node_store);
|
||||||
@@ -122,6 +124,7 @@ static int cam_req_mgr_open(struct file *filep)
|
|||||||
spin_unlock_bh(&g_dev.cam_eventq_lock);
|
spin_unlock_bh(&g_dev.cam_eventq_lock);
|
||||||
|
|
||||||
g_dev.open_cnt++;
|
g_dev.open_cnt++;
|
||||||
|
g_dev.read_active_dev_id_hdls = 0;
|
||||||
rc = cam_mem_mgr_init();
|
rc = cam_mem_mgr_init();
|
||||||
if (rc) {
|
if (rc) {
|
||||||
g_dev.open_cnt--;
|
g_dev.open_cnt--;
|
||||||
@@ -158,6 +161,7 @@ static unsigned int cam_req_mgr_poll(struct file *f,
|
|||||||
static int cam_req_mgr_close(struct file *filep)
|
static int cam_req_mgr_close(struct file *filep)
|
||||||
{
|
{
|
||||||
struct v4l2_subdev *sd;
|
struct v4l2_subdev *sd;
|
||||||
|
struct cam_subdev *csd;
|
||||||
struct v4l2_fh *vfh = filep->private_data;
|
struct v4l2_fh *vfh = filep->private_data;
|
||||||
struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
|
struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
|
||||||
|
|
||||||
@@ -172,18 +176,23 @@ static int cam_req_mgr_close(struct file *filep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cam_req_mgr_handle_core_shutdown();
|
cam_req_mgr_handle_core_shutdown();
|
||||||
|
g_dev.shutdown_state = true;
|
||||||
|
|
||||||
list_for_each_entry(sd, &g_dev.v4l2_dev->subdevs, list) {
|
list_for_each_entry(csd, &cam_req_mgr_ordered_sd_list, list) {
|
||||||
|
sd = &csd->sd;
|
||||||
if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
|
if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
|
||||||
continue;
|
continue;
|
||||||
if (sd->internal_ops && sd->internal_ops->close) {
|
if (sd->internal_ops) {
|
||||||
CAM_DBG(CAM_CRM, "Invoke subdev close for device %s",
|
CAM_DBG(CAM_CRM, "Invoke subdev close for device %s",
|
||||||
sd->name);
|
sd->name);
|
||||||
sd->internal_ops->close(sd, subdev_fh);
|
v4l2_subdev_call(sd, core, ioctl,
|
||||||
|
CAM_SD_SHUTDOWN, subdev_fh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_dev.open_cnt--;
|
g_dev.open_cnt--;
|
||||||
|
g_dev.shutdown_state = false;
|
||||||
|
g_dev.read_active_dev_id_hdls = 0;
|
||||||
v4l2_fh_release(filep);
|
v4l2_fh_release(filep);
|
||||||
|
|
||||||
spin_lock_bh(&g_dev.cam_eventq_lock);
|
spin_lock_bh(&g_dev.cam_eventq_lock);
|
||||||
@@ -660,6 +669,51 @@ void cam_subdev_notify_message(u32 subdev_type,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(cam_subdev_notify_message);
|
EXPORT_SYMBOL(cam_subdev_notify_message);
|
||||||
|
|
||||||
|
|
||||||
|
static int cam_req_mgr_ordered_list_cmp(void *priv,
|
||||||
|
struct list_head *head_1, struct list_head *head_2)
|
||||||
|
{
|
||||||
|
struct cam_subdev *entry_1 =
|
||||||
|
list_entry(head_1, struct cam_subdev, list);
|
||||||
|
struct cam_subdev *entry_2 =
|
||||||
|
list_entry(head_2, struct cam_subdev, list);
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (entry_1->close_seq_prior > entry_2->close_seq_prior)
|
||||||
|
return 1;
|
||||||
|
else if (entry_1->close_seq_prior < entry_2->close_seq_prior)
|
||||||
|
return ret;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cam_req_mgr_is_open(uint64_t dev_id)
|
||||||
|
{
|
||||||
|
bool crm_status;
|
||||||
|
bool dev_id_status;
|
||||||
|
|
||||||
|
mutex_lock(&g_dev.cam_lock);
|
||||||
|
crm_status = g_dev.open_cnt ? true : false;
|
||||||
|
|
||||||
|
if (!g_dev.read_active_dev_id_hdls) {
|
||||||
|
g_dev.active_dev_id_hdls = cam_get_dev_handle_status();
|
||||||
|
g_dev.read_active_dev_id_hdls++;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_id_status = (g_dev.active_dev_id_hdls & dev_id) ? true : false;
|
||||||
|
crm_status &= dev_id_status;
|
||||||
|
mutex_unlock(&g_dev.cam_lock);
|
||||||
|
|
||||||
|
return crm_status;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(cam_req_mgr_is_open);
|
||||||
|
|
||||||
|
bool cam_req_mgr_is_shutdown(void)
|
||||||
|
{
|
||||||
|
return g_dev.shutdown_state;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(cam_req_mgr_is_shutdown);
|
||||||
|
|
||||||
int cam_register_subdev(struct cam_subdev *csd)
|
int cam_register_subdev(struct cam_subdev *csd)
|
||||||
{
|
{
|
||||||
struct v4l2_subdev *sd;
|
struct v4l2_subdev *sd;
|
||||||
@@ -688,6 +742,10 @@ int cam_register_subdev(struct cam_subdev *csd)
|
|||||||
sd->entity.pads = NULL;
|
sd->entity.pads = NULL;
|
||||||
sd->entity.function = csd->ent_function;
|
sd->entity.function = csd->ent_function;
|
||||||
|
|
||||||
|
list_add(&csd->list, &cam_req_mgr_ordered_sd_list);
|
||||||
|
list_sort(NULL, &cam_req_mgr_ordered_sd_list,
|
||||||
|
cam_req_mgr_ordered_list_cmp);
|
||||||
|
|
||||||
rc = v4l2_device_register_subdev(g_dev.v4l2_dev, sd);
|
rc = v4l2_device_register_subdev(g_dev.v4l2_dev, sd);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
CAM_ERR(CAM_CRM, "register subdev failed");
|
CAM_ERR(CAM_CRM, "register subdev failed");
|
||||||
@@ -754,6 +812,7 @@ static int cam_req_mgr_component_master_bind(struct device *dev)
|
|||||||
goto video_setup_fail;
|
goto video_setup_fail;
|
||||||
|
|
||||||
g_dev.open_cnt = 0;
|
g_dev.open_cnt = 0;
|
||||||
|
g_dev.shutdown_state = false;
|
||||||
mutex_init(&g_dev.cam_lock);
|
mutex_init(&g_dev.cam_lock);
|
||||||
spin_lock_init(&g_dev.cam_eventq_lock);
|
spin_lock_init(&g_dev.cam_eventq_lock);
|
||||||
mutex_init(&g_dev.dev_lock);
|
mutex_init(&g_dev.dev_lock);
|
||||||
@@ -771,6 +830,7 @@ static int cam_req_mgr_component_master_bind(struct device *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_dev.state = true;
|
g_dev.state = true;
|
||||||
|
INIT_LIST_HEAD(&cam_req_mgr_ordered_sd_list);
|
||||||
|
|
||||||
if (g_cam_req_mgr_timer_cachep == NULL) {
|
if (g_cam_req_mgr_timer_cachep == NULL) {
|
||||||
g_cam_req_mgr_timer_cachep = kmem_cache_create("crm_timer",
|
g_cam_req_mgr_timer_cachep = kmem_cache_create("crm_timer",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CAM_REQ_MGR_DEV_H_
|
#ifndef _CAM_REQ_MGR_DEV_H_
|
||||||
@@ -19,6 +19,9 @@
|
|||||||
* @cam_lock: per file handle lock
|
* @cam_lock: per file handle lock
|
||||||
* @cam_eventq: event queue
|
* @cam_eventq: event queue
|
||||||
* @cam_eventq_lock: lock for event queue
|
* @cam_eventq_lock: lock for event queue
|
||||||
|
* @shutdown_state: shutdown state
|
||||||
|
* @active_dev_id_hdls: active dev id handles
|
||||||
|
* @read_active_dev_id_hdls: read active_dev_id_hdls status
|
||||||
*/
|
*/
|
||||||
struct cam_req_mgr_device {
|
struct cam_req_mgr_device {
|
||||||
struct video_device *video;
|
struct video_device *video;
|
||||||
@@ -30,6 +33,9 @@ struct cam_req_mgr_device {
|
|||||||
struct mutex cam_lock;
|
struct mutex cam_lock;
|
||||||
struct v4l2_fh *cam_eventq;
|
struct v4l2_fh *cam_eventq;
|
||||||
spinlock_t cam_eventq_lock;
|
spinlock_t cam_eventq_lock;
|
||||||
|
bool shutdown_state;
|
||||||
|
uint64_t active_dev_id_hdls;
|
||||||
|
int read_active_dev_id_hdls;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CAM_REQ_MGR_GET_PAYLOAD_PTR(ev, type) \
|
#define CAM_REQ_MGR_GET_PAYLOAD_PTR(ev, type) \
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include <media/cam_req_mgr.h>
|
#include <media/cam_req_mgr.h>
|
||||||
#include "cam_req_mgr_util.h"
|
#include "cam_req_mgr_util.h"
|
||||||
#include "cam_debug_util.h"
|
#include "cam_debug_util.h"
|
||||||
|
#include "cam_context.h"
|
||||||
|
|
||||||
static struct cam_req_mgr_util_hdl_tbl *hdl_tbl;
|
static struct cam_req_mgr_util_hdl_tbl *hdl_tbl;
|
||||||
static DEFINE_SPINLOCK(hdl_tbl_lock);
|
static DEFINE_SPINLOCK(hdl_tbl_lock);
|
||||||
@@ -209,6 +210,36 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data)
|
|||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t cam_get_dev_handle_info(uint64_t handle,
|
||||||
|
struct cam_context **ctx, int32_t dev_index)
|
||||||
|
{
|
||||||
|
int32_t idx;
|
||||||
|
struct v4l2_subdev *sd = (struct v4l2_subdev *)handle;
|
||||||
|
|
||||||
|
for (idx = dev_index + 1; idx < CAM_REQ_MGR_MAX_HANDLES_V2; idx++) {
|
||||||
|
if (hdl_tbl->hdl[idx].state == HDL_ACTIVE) {
|
||||||
|
*ctx = (struct cam_context *)cam_get_device_priv(
|
||||||
|
hdl_tbl->hdl[idx].hdl_value);
|
||||||
|
if ((*ctx) && !strcmp(sd->name, (*ctx)->dev_name))
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ctx = NULL;
|
||||||
|
return CAM_REQ_MGR_MAX_HANDLES_V2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t cam_get_dev_handle_status(void)
|
||||||
|
{
|
||||||
|
int32_t idx;
|
||||||
|
uint64_t active_dev_hdls = 0;
|
||||||
|
|
||||||
|
for (idx = 0; idx < CAM_REQ_MGR_MAX_HANDLES_V2; idx++)
|
||||||
|
if (hdl_tbl->hdl[idx].state == HDL_ACTIVE)
|
||||||
|
active_dev_hdls |= hdl_tbl->hdl[idx].dev_id;
|
||||||
|
|
||||||
|
return active_dev_hdls;
|
||||||
|
}
|
||||||
|
|
||||||
void *cam_get_device_priv(int32_t dev_hdl)
|
void *cam_get_device_priv(int32_t dev_hdl)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
|
@@ -166,4 +166,11 @@ int32_t cam_req_mgr_util_deinit(void);
|
|||||||
*/
|
*/
|
||||||
int32_t cam_req_mgr_util_free_hdls(void);
|
int32_t cam_req_mgr_util_free_hdls(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cam_get_dev_handle_status() - get dev handles status
|
||||||
|
*
|
||||||
|
* Returns dev handle status
|
||||||
|
*/
|
||||||
|
uint64_t cam_get_dev_handle_status(void);
|
||||||
|
|
||||||
#endif /* _CAM_REQ_MGR_UTIL_API_H_ */
|
#endif /* _CAM_REQ_MGR_UTIL_API_H_ */
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CAM_SUBDEV_H_
|
#ifndef _CAM_SUBDEV_H_
|
||||||
@@ -20,6 +20,13 @@ enum cam_subdev_message_type_t {
|
|||||||
CAM_SUBDEV_MESSAGE_IRQ_ERR = 0x1
|
CAM_SUBDEV_MESSAGE_IRQ_ERR = 0x1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Enum for close sequence priority */
|
||||||
|
enum cam_subdev_close_seq_priority {
|
||||||
|
CAM_SD_CLOSE_HIGH_PRIORITY,
|
||||||
|
CAM_SD_CLOSE_MEDIUM_PRIORITY,
|
||||||
|
CAM_SD_CLOSE_LOW_PRIORITY
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct cam_subdev - describes a camera sub-device
|
* struct cam_subdev - describes a camera sub-device
|
||||||
*
|
*
|
||||||
@@ -38,6 +45,8 @@ enum cam_subdev_message_type_t {
|
|||||||
* @ent_function: Media entity function type. Can be:
|
* @ent_function: Media entity function type. Can be:
|
||||||
* %CAM_IFE_DEVICE_TYPE - identifies as IFE device.
|
* %CAM_IFE_DEVICE_TYPE - identifies as IFE device.
|
||||||
* %CAM_ICP_DEVICE_TYPE - identifies as ICP device.
|
* %CAM_ICP_DEVICE_TYPE - identifies as ICP device.
|
||||||
|
* @list: list pointer
|
||||||
|
* @close_seq_prior: cam_subdev_close_seq_priority type
|
||||||
*
|
*
|
||||||
* Each instance of a subdev driver should create this struct, either
|
* Each instance of a subdev driver should create this struct, either
|
||||||
* stand-alone or embedded in a larger struct. This structure should be
|
* stand-alone or embedded in a larger struct. This structure should be
|
||||||
@@ -57,6 +66,8 @@ struct cam_subdev {
|
|||||||
struct v4l2_subdev *sd,
|
struct v4l2_subdev *sd,
|
||||||
enum cam_subdev_message_type_t msg_type,
|
enum cam_subdev_message_type_t msg_type,
|
||||||
uint32_t data);
|
uint32_t data);
|
||||||
|
struct list_head list;
|
||||||
|
enum cam_subdev_close_seq_priority close_seq_prior;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,4 +129,20 @@ int cam_register_subdev(struct cam_subdev *sd);
|
|||||||
*/
|
*/
|
||||||
int cam_unregister_subdev(struct cam_subdev *sd);
|
int cam_unregister_subdev(struct cam_subdev *sd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cam_req_mgr_is_open()
|
||||||
|
*
|
||||||
|
* @brief: This common utility function returns the crm active status
|
||||||
|
*
|
||||||
|
* @dev_id: device id type
|
||||||
|
*/
|
||||||
|
bool cam_req_mgr_is_open(uint64_t dev_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cam_req_mgr_is_shutdown()
|
||||||
|
*
|
||||||
|
* @brief: This common utility function returns the shutdown state
|
||||||
|
*/
|
||||||
|
bool cam_req_mgr_is_shutdown(void);
|
||||||
|
|
||||||
#endif /* _CAM_SUBDEV_H_ */
|
#endif /* _CAM_SUBDEV_H_ */
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cam_actuator_dev.h"
|
#include "cam_actuator_dev.h"
|
||||||
@@ -10,6 +10,38 @@
|
|||||||
#include "cam_trace.h"
|
#include "cam_trace.h"
|
||||||
#include "camera_main.h"
|
#include "camera_main.h"
|
||||||
|
|
||||||
|
static int cam_actuator_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
struct cam_actuator_ctrl_t *a_ctrl =
|
||||||
|
v4l2_get_subdevdata(sd);
|
||||||
|
|
||||||
|
if (!a_ctrl) {
|
||||||
|
CAM_ERR(CAM_ACTUATOR, "a_ctrl ptr is NULL");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&(a_ctrl->actuator_mutex));
|
||||||
|
cam_actuator_shutdown(a_ctrl);
|
||||||
|
mutex_unlock(&(a_ctrl->actuator_mutex));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cam_actuator_subdev_close(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
bool crm_active = cam_req_mgr_is_open(CAM_ACTUATOR);
|
||||||
|
|
||||||
|
if (crm_active) {
|
||||||
|
CAM_INFO(CAM_ACTUATOR,
|
||||||
|
"CRM is ACTIVE, close should be from CRM");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cam_actuator_subdev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
static long cam_actuator_subdev_ioctl(struct v4l2_subdev *sd,
|
static long cam_actuator_subdev_ioctl(struct v4l2_subdev *sd,
|
||||||
unsigned int cmd, void *arg)
|
unsigned int cmd, void *arg)
|
||||||
{
|
{
|
||||||
@@ -24,6 +56,14 @@ static long cam_actuator_subdev_ioctl(struct v4l2_subdev *sd,
|
|||||||
CAM_ERR(CAM_ACTUATOR,
|
CAM_ERR(CAM_ACTUATOR,
|
||||||
"Failed for driver_cmd: %d", rc);
|
"Failed for driver_cmd: %d", rc);
|
||||||
break;
|
break;
|
||||||
|
case CAM_SD_SHUTDOWN:
|
||||||
|
if (!cam_req_mgr_is_shutdown()) {
|
||||||
|
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = cam_actuator_subdev_close_internal(sd, NULL);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
CAM_ERR(CAM_ACTUATOR, "Invalid ioctl cmd: %u", cmd);
|
CAM_ERR(CAM_ACTUATOR, "Invalid ioctl cmd: %u", cmd);
|
||||||
rc = -ENOIOCTLCMD;
|
rc = -ENOIOCTLCMD;
|
||||||
@@ -77,24 +117,6 @@ static long cam_actuator_init_subdev_do_ioctl(struct v4l2_subdev *sd,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int cam_actuator_subdev_close(struct v4l2_subdev *sd,
|
|
||||||
struct v4l2_subdev_fh *fh)
|
|
||||||
{
|
|
||||||
struct cam_actuator_ctrl_t *a_ctrl =
|
|
||||||
v4l2_get_subdevdata(sd);
|
|
||||||
|
|
||||||
if (!a_ctrl) {
|
|
||||||
CAM_ERR(CAM_ACTUATOR, "a_ctrl ptr is NULL");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_lock(&(a_ctrl->actuator_mutex));
|
|
||||||
cam_actuator_shutdown(a_ctrl);
|
|
||||||
mutex_unlock(&(a_ctrl->actuator_mutex));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct v4l2_subdev_core_ops cam_actuator_subdev_core_ops = {
|
static struct v4l2_subdev_core_ops cam_actuator_subdev_core_ops = {
|
||||||
.ioctl = cam_actuator_subdev_ioctl,
|
.ioctl = cam_actuator_subdev_ioctl,
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
@@ -127,10 +149,13 @@ static int cam_actuator_init_subdev(struct cam_actuator_ctrl_t *a_ctrl)
|
|||||||
a_ctrl->v4l2_dev_str.ent_function =
|
a_ctrl->v4l2_dev_str.ent_function =
|
||||||
CAM_ACTUATOR_DEVICE_TYPE;
|
CAM_ACTUATOR_DEVICE_TYPE;
|
||||||
a_ctrl->v4l2_dev_str.token = a_ctrl;
|
a_ctrl->v4l2_dev_str.token = a_ctrl;
|
||||||
|
a_ctrl->v4l2_dev_str.close_seq_prior =
|
||||||
|
CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||||
|
|
||||||
rc = cam_register_subdev(&(a_ctrl->v4l2_dev_str));
|
rc = cam_register_subdev(&(a_ctrl->v4l2_dev_str));
|
||||||
if (rc)
|
if (rc)
|
||||||
CAM_ERR(CAM_SENSOR, "Fail with cam_register_subdev rc: %d", rc);
|
CAM_ERR(CAM_ACTUATOR,
|
||||||
|
"Fail with cam_register_subdev rc: %d", rc);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@@ -92,29 +92,7 @@ static void cam_csiphy_debug_unregister(void)
|
|||||||
root_dentry = NULL;
|
root_dentry = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long cam_csiphy_subdev_ioctl(struct v4l2_subdev *sd,
|
static int cam_csiphy_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
unsigned int cmd, void *arg)
|
|
||||||
{
|
|
||||||
struct csiphy_device *csiphy_dev = v4l2_get_subdevdata(sd);
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
switch (cmd) {
|
|
||||||
case VIDIOC_CAM_CONTROL:
|
|
||||||
rc = cam_csiphy_core_cfg(csiphy_dev, arg);
|
|
||||||
if (rc)
|
|
||||||
CAM_ERR(CAM_CSIPHY,
|
|
||||||
"Failed in configuring the device: %d", rc);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
CAM_ERR(CAM_CSIPHY, "Wrong ioctl : %d", cmd);
|
|
||||||
rc = -ENOIOCTLCMD;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cam_csiphy_subdev_close(struct v4l2_subdev *sd,
|
|
||||||
struct v4l2_subdev_fh *fh)
|
struct v4l2_subdev_fh *fh)
|
||||||
{
|
{
|
||||||
struct csiphy_device *csiphy_dev =
|
struct csiphy_device *csiphy_dev =
|
||||||
@@ -132,6 +110,49 @@ static int cam_csiphy_subdev_close(struct v4l2_subdev *sd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cam_csiphy_subdev_close(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
bool crm_active = cam_req_mgr_is_open(CAM_CSIPHY);
|
||||||
|
|
||||||
|
if (crm_active) {
|
||||||
|
CAM_INFO(CAM_CSIPHY, "CRM is ACTIVE, close should be from CRM");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cam_csiphy_subdev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
|
static long cam_csiphy_subdev_ioctl(struct v4l2_subdev *sd,
|
||||||
|
unsigned int cmd, void *arg)
|
||||||
|
{
|
||||||
|
struct csiphy_device *csiphy_dev = v4l2_get_subdevdata(sd);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case VIDIOC_CAM_CONTROL:
|
||||||
|
rc = cam_csiphy_core_cfg(csiphy_dev, arg);
|
||||||
|
if (rc)
|
||||||
|
CAM_ERR(CAM_CSIPHY,
|
||||||
|
"Failed in configuring the device: %d", rc);
|
||||||
|
break;
|
||||||
|
case CAM_SD_SHUTDOWN:
|
||||||
|
if (!cam_req_mgr_is_shutdown()) {
|
||||||
|
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = cam_csiphy_subdev_close_internal(sd, NULL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CAM_ERR(CAM_CSIPHY, "Wrong ioctl : %d", cmd);
|
||||||
|
rc = -ENOIOCTLCMD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
static long cam_csiphy_subdev_compat_ioctl(struct v4l2_subdev *sd,
|
static long cam_csiphy_subdev_compat_ioctl(struct v4l2_subdev *sd,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
@@ -246,6 +267,8 @@ static int cam_csiphy_component_bind(struct device *dev,
|
|||||||
cam_csiphy_subdev_handle_message;
|
cam_csiphy_subdev_handle_message;
|
||||||
new_csiphy_dev->v4l2_dev_str.token =
|
new_csiphy_dev->v4l2_dev_str.token =
|
||||||
new_csiphy_dev;
|
new_csiphy_dev;
|
||||||
|
new_csiphy_dev->v4l2_dev_str.close_seq_prior =
|
||||||
|
CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||||
|
|
||||||
rc = cam_register_subdev(&(new_csiphy_dev->v4l2_dev_str));
|
rc = cam_register_subdev(&(new_csiphy_dev->v4l2_dev_str));
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cam_eeprom_dev.h"
|
#include "cam_eeprom_dev.h"
|
||||||
@@ -10,28 +10,7 @@
|
|||||||
#include "cam_debug_util.h"
|
#include "cam_debug_util.h"
|
||||||
#include "camera_main.h"
|
#include "camera_main.h"
|
||||||
|
|
||||||
static long cam_eeprom_subdev_ioctl(struct v4l2_subdev *sd,
|
static int cam_eeprom_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
unsigned int cmd, void *arg)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
struct cam_eeprom_ctrl_t *e_ctrl = v4l2_get_subdevdata(sd);
|
|
||||||
|
|
||||||
switch (cmd) {
|
|
||||||
case VIDIOC_CAM_CONTROL:
|
|
||||||
rc = cam_eeprom_driver_cmd(e_ctrl, arg);
|
|
||||||
if (rc)
|
|
||||||
CAM_ERR(CAM_EEPROM,
|
|
||||||
"Failed in Driver cmd: %d", rc);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
rc = -ENOIOCTLCMD;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cam_eeprom_subdev_close(struct v4l2_subdev *sd,
|
|
||||||
struct v4l2_subdev_fh *fh)
|
struct v4l2_subdev_fh *fh)
|
||||||
{
|
{
|
||||||
struct cam_eeprom_ctrl_t *e_ctrl =
|
struct cam_eeprom_ctrl_t *e_ctrl =
|
||||||
@@ -49,6 +28,48 @@ static int cam_eeprom_subdev_close(struct v4l2_subdev *sd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cam_eeprom_subdev_close(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
bool crm_active = cam_req_mgr_is_open(CAM_EEPROM);
|
||||||
|
|
||||||
|
if (crm_active) {
|
||||||
|
CAM_INFO(CAM_EEPROM, "CRM is ACTIVE, close should be from CRM");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cam_eeprom_subdev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
|
static long cam_eeprom_subdev_ioctl(struct v4l2_subdev *sd,
|
||||||
|
unsigned int cmd, void *arg)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct cam_eeprom_ctrl_t *e_ctrl = v4l2_get_subdevdata(sd);
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case VIDIOC_CAM_CONTROL:
|
||||||
|
rc = cam_eeprom_driver_cmd(e_ctrl, arg);
|
||||||
|
if (rc)
|
||||||
|
CAM_ERR(CAM_EEPROM,
|
||||||
|
"Failed in Driver cmd: %d", rc);
|
||||||
|
break;
|
||||||
|
case CAM_SD_SHUTDOWN:
|
||||||
|
if (!cam_req_mgr_is_shutdown()) {
|
||||||
|
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = cam_eeprom_subdev_close_internal(sd, NULL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rc = -ENOIOCTLCMD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t cam_eeprom_update_i2c_info(struct cam_eeprom_ctrl_t *e_ctrl,
|
int32_t cam_eeprom_update_i2c_info(struct cam_eeprom_ctrl_t *e_ctrl,
|
||||||
struct cam_eeprom_i2c_info_t *i2c_info)
|
struct cam_eeprom_i2c_info_t *i2c_info)
|
||||||
{
|
{
|
||||||
@@ -147,6 +168,7 @@ static int cam_eeprom_init_subdev(struct cam_eeprom_ctrl_t *e_ctrl)
|
|||||||
(V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS);
|
(V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS);
|
||||||
e_ctrl->v4l2_dev_str.ent_function = CAM_EEPROM_DEVICE_TYPE;
|
e_ctrl->v4l2_dev_str.ent_function = CAM_EEPROM_DEVICE_TYPE;
|
||||||
e_ctrl->v4l2_dev_str.token = e_ctrl;
|
e_ctrl->v4l2_dev_str.token = e_ctrl;
|
||||||
|
e_ctrl->v4l2_dev_str.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||||
|
|
||||||
rc = cam_register_subdev(&(e_ctrl->v4l2_dev_str));
|
rc = cam_register_subdev(&(e_ctrl->v4l2_dev_str));
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
@@ -236,6 +236,37 @@ static const struct of_device_id cam_flash_dt_match[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int cam_flash_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
struct cam_flash_ctrl *fctrl =
|
||||||
|
v4l2_get_subdevdata(sd);
|
||||||
|
|
||||||
|
if (!fctrl) {
|
||||||
|
CAM_ERR(CAM_FLASH, "Flash ctrl ptr is NULL");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&fctrl->flash_mutex);
|
||||||
|
cam_flash_shutdown(fctrl);
|
||||||
|
mutex_unlock(&fctrl->flash_mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cam_flash_subdev_close(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
bool crm_active = cam_req_mgr_is_open(CAM_FLASH);
|
||||||
|
|
||||||
|
if (crm_active) {
|
||||||
|
CAM_INFO(CAM_FLASH, "CRM is ACTIVE, close should be from CRM");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cam_flash_subdev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
static long cam_flash_subdev_ioctl(struct v4l2_subdev *sd,
|
static long cam_flash_subdev_ioctl(struct v4l2_subdev *sd,
|
||||||
unsigned int cmd, void *arg)
|
unsigned int cmd, void *arg)
|
||||||
{
|
{
|
||||||
@@ -257,6 +288,14 @@ static long cam_flash_subdev_ioctl(struct v4l2_subdev *sd,
|
|||||||
"Failed in driver cmd: %d", rc);
|
"Failed in driver cmd: %d", rc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CAM_SD_SHUTDOWN:
|
||||||
|
if (!cam_req_mgr_is_shutdown()) {
|
||||||
|
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = cam_flash_subdev_close_internal(sd, NULL);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
CAM_ERR(CAM_FLASH, "Invalid ioctl cmd type");
|
CAM_ERR(CAM_FLASH, "Invalid ioctl cmd type");
|
||||||
rc = -ENOIOCTLCMD;
|
rc = -ENOIOCTLCMD;
|
||||||
@@ -328,24 +367,6 @@ static int32_t cam_flash_i2c_driver_remove(struct i2c_client *client)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cam_flash_subdev_close(struct v4l2_subdev *sd,
|
|
||||||
struct v4l2_subdev_fh *fh)
|
|
||||||
{
|
|
||||||
struct cam_flash_ctrl *fctrl =
|
|
||||||
v4l2_get_subdevdata(sd);
|
|
||||||
|
|
||||||
if (!fctrl) {
|
|
||||||
CAM_ERR(CAM_FLASH, "Flash ctrl ptr is NULL");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_lock(&fctrl->flash_mutex);
|
|
||||||
cam_flash_shutdown(fctrl);
|
|
||||||
mutex_unlock(&fctrl->flash_mutex);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct v4l2_subdev_core_ops cam_flash_subdev_core_ops = {
|
static struct v4l2_subdev_core_ops cam_flash_subdev_core_ops = {
|
||||||
.ioctl = cam_flash_subdev_ioctl,
|
.ioctl = cam_flash_subdev_ioctl,
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
@@ -375,6 +396,7 @@ static int cam_flash_init_subdev(struct cam_flash_ctrl *fctrl)
|
|||||||
V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
|
V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
|
||||||
fctrl->v4l2_dev_str.ent_function = CAM_FLASH_DEVICE_TYPE;
|
fctrl->v4l2_dev_str.ent_function = CAM_FLASH_DEVICE_TYPE;
|
||||||
fctrl->v4l2_dev_str.token = fctrl;
|
fctrl->v4l2_dev_str.token = fctrl;
|
||||||
|
fctrl->v4l2_dev_str.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||||
|
|
||||||
rc = cam_register_subdev(&(fctrl->v4l2_dev_str));
|
rc = cam_register_subdev(&(fctrl->v4l2_dev_str));
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@@ -10,29 +10,7 @@
|
|||||||
#include "cam_debug_util.h"
|
#include "cam_debug_util.h"
|
||||||
#include "camera_main.h"
|
#include "camera_main.h"
|
||||||
|
|
||||||
static long cam_ois_subdev_ioctl(struct v4l2_subdev *sd,
|
static int cam_ois_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
unsigned int cmd, void *arg)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
struct cam_ois_ctrl_t *o_ctrl = v4l2_get_subdevdata(sd);
|
|
||||||
|
|
||||||
switch (cmd) {
|
|
||||||
case VIDIOC_CAM_CONTROL:
|
|
||||||
rc = cam_ois_driver_cmd(o_ctrl, arg);
|
|
||||||
if (rc)
|
|
||||||
CAM_ERR(CAM_OIS,
|
|
||||||
"Failed with driver cmd: %d", rc);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
CAM_ERR(CAM_OIS, "Wrong IOCTL cmd: %u", cmd);
|
|
||||||
rc = -ENOIOCTLCMD;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cam_ois_subdev_close(struct v4l2_subdev *sd,
|
|
||||||
struct v4l2_subdev_fh *fh)
|
struct v4l2_subdev_fh *fh)
|
||||||
{
|
{
|
||||||
struct cam_ois_ctrl_t *o_ctrl =
|
struct cam_ois_ctrl_t *o_ctrl =
|
||||||
@@ -50,6 +28,48 @@ static int cam_ois_subdev_close(struct v4l2_subdev *sd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cam_ois_subdev_close(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
bool crm_active = cam_req_mgr_is_open(CAM_OIS);
|
||||||
|
|
||||||
|
if (crm_active) {
|
||||||
|
CAM_INFO(CAM_OIS, "CRM is ACTIVE, close should be from CRM");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cam_ois_subdev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
|
static long cam_ois_subdev_ioctl(struct v4l2_subdev *sd,
|
||||||
|
unsigned int cmd, void *arg)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct cam_ois_ctrl_t *o_ctrl = v4l2_get_subdevdata(sd);
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case VIDIOC_CAM_CONTROL:
|
||||||
|
rc = cam_ois_driver_cmd(o_ctrl, arg);
|
||||||
|
if (rc)
|
||||||
|
CAM_ERR(CAM_OIS,
|
||||||
|
"Failed with driver cmd: %d", rc);
|
||||||
|
break;
|
||||||
|
case CAM_SD_SHUTDOWN:
|
||||||
|
if (!cam_req_mgr_is_shutdown()) {
|
||||||
|
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
rc = cam_ois_subdev_close_internal(sd, NULL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CAM_ERR(CAM_OIS, "Wrong IOCTL cmd: %u", cmd);
|
||||||
|
rc = -ENOIOCTLCMD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t cam_ois_update_i2c_info(struct cam_ois_ctrl_t *o_ctrl,
|
static int32_t cam_ois_update_i2c_info(struct cam_ois_ctrl_t *o_ctrl,
|
||||||
struct cam_ois_i2c_info_t *i2c_info)
|
struct cam_ois_i2c_info_t *i2c_info)
|
||||||
{
|
{
|
||||||
@@ -144,6 +164,7 @@ static int cam_ois_init_subdev_param(struct cam_ois_ctrl_t *o_ctrl)
|
|||||||
(V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS);
|
(V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS);
|
||||||
o_ctrl->v4l2_dev_str.ent_function = CAM_OIS_DEVICE_TYPE;
|
o_ctrl->v4l2_dev_str.ent_function = CAM_OIS_DEVICE_TYPE;
|
||||||
o_ctrl->v4l2_dev_str.token = o_ctrl;
|
o_ctrl->v4l2_dev_str.token = o_ctrl;
|
||||||
|
o_ctrl->v4l2_dev_str.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||||
|
|
||||||
rc = cam_register_subdev(&(o_ctrl->v4l2_dev_str));
|
rc = cam_register_subdev(&(o_ctrl->v4l2_dev_str));
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cam_sensor_dev.h"
|
#include "cam_sensor_dev.h"
|
||||||
@@ -9,29 +9,7 @@
|
|||||||
#include "cam_sensor_core.h"
|
#include "cam_sensor_core.h"
|
||||||
#include "camera_main.h"
|
#include "camera_main.h"
|
||||||
|
|
||||||
static long cam_sensor_subdev_ioctl(struct v4l2_subdev *sd,
|
static int cam_sensor_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
unsigned int cmd, void *arg)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
struct cam_sensor_ctrl_t *s_ctrl =
|
|
||||||
v4l2_get_subdevdata(sd);
|
|
||||||
|
|
||||||
switch (cmd) {
|
|
||||||
case VIDIOC_CAM_CONTROL:
|
|
||||||
rc = cam_sensor_driver_cmd(s_ctrl, arg);
|
|
||||||
if (rc)
|
|
||||||
CAM_ERR(CAM_SENSOR,
|
|
||||||
"Failed in Driver cmd: %d", rc);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
CAM_ERR(CAM_SENSOR, "Invalid ioctl cmd: %d", cmd);
|
|
||||||
rc = -ENOIOCTLCMD;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cam_sensor_subdev_close(struct v4l2_subdev *sd,
|
|
||||||
struct v4l2_subdev_fh *fh)
|
struct v4l2_subdev_fh *fh)
|
||||||
{
|
{
|
||||||
struct cam_sensor_ctrl_t *s_ctrl =
|
struct cam_sensor_ctrl_t *s_ctrl =
|
||||||
@@ -49,6 +27,49 @@ static int cam_sensor_subdev_close(struct v4l2_subdev *sd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cam_sensor_subdev_close(struct v4l2_subdev *sd,
|
||||||
|
struct v4l2_subdev_fh *fh)
|
||||||
|
{
|
||||||
|
bool crm_active = cam_req_mgr_is_open(CAM_SENSOR);
|
||||||
|
|
||||||
|
if (crm_active) {
|
||||||
|
CAM_INFO(CAM_SENSOR, "CRM is ACTIVE, close should be from CRM");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cam_sensor_subdev_close_internal(sd, fh);
|
||||||
|
}
|
||||||
|
|
||||||
|
static long cam_sensor_subdev_ioctl(struct v4l2_subdev *sd,
|
||||||
|
unsigned int cmd, void *arg)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct cam_sensor_ctrl_t *s_ctrl =
|
||||||
|
v4l2_get_subdevdata(sd);
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case VIDIOC_CAM_CONTROL:
|
||||||
|
rc = cam_sensor_driver_cmd(s_ctrl, arg);
|
||||||
|
if (rc)
|
||||||
|
CAM_ERR(CAM_SENSOR,
|
||||||
|
"Failed in Driver cmd: %d", rc);
|
||||||
|
break;
|
||||||
|
case CAM_SD_SHUTDOWN:
|
||||||
|
if (!cam_req_mgr_is_shutdown()) {
|
||||||
|
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = cam_sensor_subdev_close_internal(sd, NULL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CAM_ERR(CAM_SENSOR, "Invalid ioctl cmd: %d", cmd);
|
||||||
|
rc = -ENOIOCTLCMD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
static long cam_sensor_init_subdev_do_ioctl(struct v4l2_subdev *sd,
|
static long cam_sensor_init_subdev_do_ioctl(struct v4l2_subdev *sd,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
@@ -122,6 +143,8 @@ static int cam_sensor_init_subdev_params(struct cam_sensor_ctrl_t *s_ctrl)
|
|||||||
s_ctrl->v4l2_dev_str.ent_function =
|
s_ctrl->v4l2_dev_str.ent_function =
|
||||||
CAM_SENSOR_DEVICE_TYPE;
|
CAM_SENSOR_DEVICE_TYPE;
|
||||||
s_ctrl->v4l2_dev_str.token = s_ctrl;
|
s_ctrl->v4l2_dev_str.token = s_ctrl;
|
||||||
|
s_ctrl->v4l2_dev_str.close_seq_prior =
|
||||||
|
CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||||
|
|
||||||
rc = cam_register_subdev(&(s_ctrl->v4l2_dev_str));
|
rc = cam_register_subdev(&(s_ctrl->v4l2_dev_str));
|
||||||
if (rc)
|
if (rc)
|
||||||
|
Reference in New Issue
Block a user