From 2bc5c937f37d5a6ba76d4eb32e370f10df9d1ac5 Mon Sep 17 00:00:00 2001 From: Iliya Varadzhakov Date: Wed, 21 Dec 2016 18:30:12 +0200 Subject: [PATCH] msm:cci: Add protection for race condition in cci queue access If two sensors are connected to the same CCI bus they start to write to this bus asynchronously. In some cases first sensor will start to write to the bus whle the second sensor call cci init function. Such race condition causes cci queue timeout To avoid such race condition cci init needs to be protected with queue mutexes. Change-Id: Ie8acf1c6543475a5b0b494c826d4af47573d0db3 Signed-off-by: Iliya Varadzhakov --- .../media/platform/msm/camera_v2/sensor/cci/msm_cci.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c index 12d5d7eeb368..48872334cd83 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c +++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, 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 @@ -1284,6 +1284,10 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd, CDBG("%s:%d master %d\n", __func__, __LINE__, master); if (master < MASTER_MAX && master >= 0) { mutex_lock(&cci_dev->cci_master_info[master].mutex); + mutex_lock(&cci_dev->cci_master_info[master]. + mutex_q[PRIORITY_QUEUE]); + mutex_lock(&cci_dev->cci_master_info[master]. + mutex_q[SYNC_QUEUE]); flush_workqueue(cci_dev->write_wq[master]); /* Re-initialize the completion */ reinit_completion(&cci_dev-> @@ -1308,6 +1312,10 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd, if (rc <= 0) pr_err("%s:%d wait failed %d\n", __func__, __LINE__, rc); + mutex_unlock(&cci_dev->cci_master_info[master]. + mutex_q[SYNC_QUEUE]); + mutex_unlock(&cci_dev->cci_master_info[master]. + mutex_q[PRIORITY_QUEUE]); mutex_unlock(&cci_dev->cci_master_info[master].mutex); } return 0;