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

Commit cf52e098 authored by Om Parkash's avatar Om Parkash Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: Add mutex to avoid race condition for cci dev



When cci device is accessed by multiple clients simultaneously,
reference count will be out of sync. So adding Mutex to protect
cci params and state change during simultaneous access.

Change-Id: I1e26176c7c2ea11170cc944000e68058c8a90b74
Signed-off-by: default avatarOm Parkash <oparkash@codeaurora.org>
parent 88454853
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -559,7 +559,6 @@ void cam_cci_get_clk_rates(struct cci_device *cci_dev,
			return;
		}
	}
	return;
}

static int32_t cam_cci_set_clk_param(struct cci_device *cci_dev,
@@ -1604,14 +1603,27 @@ int32_t cam_cci_core_cfg(struct v4l2_subdev *sd,
	struct cam_cci_ctrl *cci_ctrl)
{
	int32_t rc = 0;
	struct cci_device *cci_dev;

	cci_dev = v4l2_get_subdevdata(sd);
	if (!cci_dev || !cci_ctrl) {
		CAM_ERR(CAM_CCI, "failed: invalid params %pK %pK",
			cci_dev, cci_ctrl);
		rc = -EINVAL;
		return rc;
	}

	CAM_DBG(CAM_CCI, "cmd %d", cci_ctrl->cmd);
	switch (cci_ctrl->cmd) {
	case MSM_CCI_INIT:
		mutex_lock(&cci_dev->init_mutex);
		rc = cam_cci_init(sd, cci_ctrl);
		mutex_unlock(&cci_dev->init_mutex);
		break;
	case MSM_CCI_RELEASE:
		mutex_lock(&cci_dev->init_mutex);
		rc = cam_cci_release(sd);
		mutex_unlock(&cci_dev->init_mutex);
		break;
	case MSM_CCI_I2C_READ:
		rc = cam_cci_read_bytes(sd, cci_ctrl);
+5 −1
Original line number Diff line number Diff line
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -26,6 +26,7 @@
#include <linux/timer.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <media/cam_sensor.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
@@ -198,6 +199,8 @@ enum cam_cci_state_t {
 * @lock_status: to protect changes to irq_status1
 * @is_burst_read: Flag to determine if we are performing
 *                 a burst read operation or not
 * @init_mutex: Mutex for maintaining refcount for attached
 *              devices to cci during init/deinit.
 */
struct cci_device {
	struct v4l2_subdev subdev;
@@ -225,6 +228,7 @@ struct cci_device {
	uint32_t irq_status1;
	spinlock_t lock_status;
	bool is_burst_read;
	struct mutex init_mutex;
};

enum cam_cci_i2c_cmd_type {
+4 −2
Original line number Diff line number Diff line
@@ -93,9 +93,9 @@ int cam_cci_init(struct v4l2_subdev *sd,

	rc = cam_cpas_start(cci_dev->cpas_handle,
		&ahb_vote, &axi_vote);
	if (rc != 0) {
	if (rc != 0)
		CAM_ERR(CAM_CCI, "CPAS start failed");
	}

	cam_cci_get_clk_rates(cci_dev, c_ctrl);

	/* Re-initialize the completion */
@@ -218,6 +218,8 @@ static void cam_cci_init_cci_params(struct cci_device *new_cci_dev)
				&new_cci_dev->cci_master_info[i].lock_q[j]);
		}
	}
	mutex_init(&new_cci_dev->init_mutex);
	new_cci_dev->cci_state = CCI_STATE_DISABLED;
	spin_lock_init(&new_cci_dev->lock_status);
}