Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8564c269 authored by Alok Chauhan's avatar Alok Chauhan
Browse files

msm: camera: req_mgr: Enhance camera v4l2 subdev shutdown sequence



when provider crash occurred, there was a CSID lane overflow
observed due to shutdown sequence from CRM(sensor, csid, csiphy).
To fix the issue need to change the shutdown sequence
(csid, sensor, csiphy).

This change will update the devices sequence in order while registering
and close the sequence accordingly.

CRs-Fixed: 2852076
Change-Id: Ia6d8022e995823bf031400c33528eb8544dc2e29
Signed-off-by: default avatarAlok Chauhan <alokc@codeaurora.org>
parent 4bebb220
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -608,6 +608,31 @@ int cam_context_handle_stop_dev(struct cam_context *ctx,
	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,
	enum cam_context_dump_id id)
{
+17 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/kref.h>
#include <media/v4l2-subdev.h>
#include "cam_req_mgr_interface.h"
#include "cam_hw_mgr_intf.h"
#include "cam_smmu_api.h"
@@ -95,6 +96,7 @@ struct cam_ctx_request {
 * @acquire_hw:            Function pointer for acquire hw
 * @release_hw:            Function pointer for release hw
 * @dump_dev:              Function pointer for dump dev
 * @shutdown_dev:          Function pointer for shutdown dev
 *
 */
struct cam_ctx_ioctl_ops {
@@ -114,6 +116,8 @@ struct cam_ctx_ioctl_ops {
	int (*release_hw)(struct cam_context *ctx, void *args);
	int (*dump_dev)(struct cam_context *ctx,
			struct cam_dump_req_cmd *cmd);
	int (*shutdown_dev)(struct v4l2_subdev *sd,
			struct v4l2_subdev_fh *fh);
};

/**
@@ -494,6 +498,19 @@ int cam_context_handle_start_dev(struct cam_context *ctx,
int cam_context_handle_stop_dev(struct cam_context *ctx,
		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()
 *
+21 −0
Original line number Diff line number Diff line
@@ -297,6 +297,27 @@ static int __cam_node_handle_stop_dev(struct cam_node *node,
	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,
	struct cam_config_dev_cmd *config)
{
+27 −1
Original line number Diff line number Diff line
/* 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_
@@ -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);

/**
 * 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_ */
+16 −1
Original line number Diff line number Diff line
// 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"
@@ -45,6 +45,8 @@ static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd,
	long rc;
	struct cam_node *node =
		(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) {
		rc = -EINVAL;
@@ -56,6 +58,19 @@ static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd,
		rc = cam_node_handle_ioctl(node,
			(struct cam_control *) arg);
		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:
		CAM_ERR(CAM_CORE, "Invalid command %d for %s", cmd,
			node->name);
Loading