From patchwork Fri Sep 21 09:01:23 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sylwester Nawrocki/Kernel \\(PLT\\) /SRPOL/Staff Engineer/Samsung Electronics" X-Patchwork-Id: 1490581 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id E79363FE65 for ; Fri, 21 Sep 2012 09:01:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932143Ab2IUJBk (ORCPT ); Fri, 21 Sep 2012 05:01:40 -0400 Received: from mailout1.samsung.com ([203.254.224.24]:16014 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932070Ab2IUJBi (ORCPT ); Fri, 21 Sep 2012 05:01:38 -0400 Received: from epcpsbgm1.samsung.com (epcpsbgm1 [203.254.230.26]) by mailout1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MAO000XQZOU1CW0@mailout1.samsung.com>; Fri, 21 Sep 2012 18:01:37 +0900 (KST) X-AuditID: cbfee61a-b7f726d000000ec7-02-505c2cf12112 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 46.6A.03783.1FC2C505; Fri, 21 Sep 2012 18:01:37 +0900 (KST) Received: from amdc248.digital.local ([106.116.147.32]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MAO00ACTZQEUW30@mmp1.samsung.com>; Fri, 21 Sep 2012 18:01:37 +0900 (KST) From: Sylwester Nawrocki To: linux-media@vger.kernel.org Cc: kyungmin.park@samsung.com, sw0312.kim@samsung.com, linux-samsung-soc@vger.kernel.org, Sylwester Nawrocki Subject: [PATCH 2/2] m5mols: Protect driver data with a mutex Date: Fri, 21 Sep 2012 11:01:23 +0200 Message-id: <1348218083-32201-2-git-send-email-s.nawrocki@samsung.com> X-Mailer: git-send-email 1.7.11.3 In-reply-to: <1348218083-32201-1-git-send-email-s.nawrocki@samsung.com> References: <1348218083-32201-1-git-send-email-s.nawrocki@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrBJMWRmVeSWpSXmKPExsVy+t9jAd2POjEBBvc/cVj0bNjKajHj/D4m ByaPz5vkAhijuGxSUnMyy1KL9O0SuDI+L77LUtBjWtG2/RN7A+MPrS5GTg4JAROJHwvWskDY YhIX7q1n62Lk4hASWMQo0XHqPJTTziSx884+sCo2AUOJ3qN9jCC2iIC8xJPeG2BFzALtjBL/ 33xkAkkIC9hKHN30hw3EZhFQlXhz4xsziM0r4CYx98oFdoh1ihI/vq8Bi3MKuEu0vl7PCmIL AdXM2HuAbQIj7wJGhlWMoqkFyQXFSem5hnrFibnFpXnpesn5uZsYwf5/JrWDcWWDxSFGAQ5G JR7eFd+iA4RYE8uKK3MPMUpwMCuJ8D6KAQrxpiRWVqUW5ccXleakFh9ilOZgURLnFf4UGCAk kJ5YkpqdmlqQWgSTZeLglGpgnCvu9UFJ/orMLu6ILyESlz3kmNOLbu8u5D3sed9zwnaDyfN8 92utOmtz0PLVDo7wf1N02pKbPD462l3mcnlW8Gup0gaVj82Lru1JZEv/92zyondT057N5Xxo n2LM9CO5SqDR98EziZpJZq5vaq8bn9cumn3epvLylhV+Kzk1Ft00Xx0s8kWZQYmlOCPRUIu5 qDgRAHJz/o/7AQAA Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Without the locking the driver's data could get corrupted when the subdev is accessed from user space and from host driver by multiple processes. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/video/m5mols/m5mols.h | 18 +++++--- drivers/media/video/m5mols/m5mols_core.c | 77 +++++++++++++++++++++----------- 2 files changed, 62 insertions(+), 33 deletions(-) diff --git a/drivers/media/video/m5mols/m5mols.h b/drivers/media/video/m5mols/m5mols.h index bb58991..15d3a4f 100644 --- a/drivers/media/video/m5mols/m5mols.h +++ b/drivers/media/video/m5mols/m5mols.h @@ -155,8 +155,6 @@ struct m5mols_version { * @pdata: platform data * @sd: v4l-subdev instance * @pad: media pad - * @ffmt: current fmt according to resolution type - * @res_type: current resolution type * @irq_waitq: waitqueue for the capture * @irq_done: set to 1 in the interrupt handler * @handle: control handler @@ -174,6 +172,10 @@ struct m5mols_version { * @wdr: wide dynamic range control * @stabilization: image stabilization control * @jpeg_quality: JPEG compression quality control + * @set_power: optional power callback to the board code + * @lock: mutex protecting the structure fields below + * @ffmt: current fmt according to resolution type + * @res_type: current resolution type * @ver: information of the version * @cap: the capture mode attributes * @isp_ready: 1 when the ISP controller has completed booting @@ -181,14 +183,11 @@ struct m5mols_version { * @ctrl_sync: 1 when the control handler state is restored in H/W * @resolution: register value for current resolution * @mode: register value for current operation mode - * @set_power: optional power callback to the board code */ struct m5mols_info { const struct m5mols_platform_data *pdata; struct v4l2_subdev sd; struct media_pad pad; - struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX]; - int res_type; wait_queue_head_t irq_waitq; atomic_t irq_done; @@ -216,6 +215,13 @@ struct m5mols_info { struct v4l2_ctrl *stabilization; struct v4l2_ctrl *jpeg_quality; + int (*set_power)(struct device *dev, int on); + + struct mutex lock; + + struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX]; + int res_type; + struct m5mols_version ver; struct m5mols_capture cap; @@ -225,8 +231,6 @@ struct m5mols_info { u8 resolution; u8 mode; - - int (*set_power)(struct device *dev, int on); }; #define is_available_af(__info) (__info->ver.af) diff --git a/drivers/media/video/m5mols/m5mols_core.c b/drivers/media/video/m5mols/m5mols_core.c index cbb6381..5d108fe 100644 --- a/drivers/media/video/m5mols/m5mols_core.c +++ b/drivers/media/video/m5mols/m5mols_core.c @@ -551,13 +551,18 @@ static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, { struct m5mols_info *info = to_m5mols(sd); struct v4l2_mbus_framefmt *format; + int ret = 0; + + mutex_lock(&info->lock); format = __find_format(info, fh, fmt->which, info->res_type); if (!format) - return -EINVAL; + fmt->format = *format; + else + ret = -EINVAL; - fmt->format = *format; - return 0; + mutex_unlock(&info->lock); + return ret; } static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, @@ -578,6 +583,7 @@ static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, if (!sfmt) return 0; + mutex_lock(&info->lock); format->code = m5mols_default_ffmt[type].code; format->colorspace = V4L2_COLORSPACE_JPEG; @@ -589,7 +595,8 @@ static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, info->res_type = type; } - return 0; + mutex_unlock(&info->lock); + return ret; } static int m5mols_enum_mbus_code(struct v4l2_subdev *sd, @@ -661,20 +668,25 @@ static int m5mols_start_monitor(struct m5mols_info *info) static int m5mols_s_stream(struct v4l2_subdev *sd, int enable) { struct m5mols_info *info = to_m5mols(sd); - u32 code = info->ffmt[info->res_type].code; + u32 code; + int ret; - if (enable) { - int ret = -EINVAL; + mutex_lock(&info->lock); + code = info->ffmt[info->res_type].code; + if (enable) { if (is_code(code, M5MOLS_RESTYPE_MONITOR)) ret = m5mols_start_monitor(info); if (is_code(code, M5MOLS_RESTYPE_CAPTURE)) ret = m5mols_start_capture(info); - - return ret; + else + ret = -EINVAL; + } else { + ret = m5mols_set_mode(info, REG_PARAMETER); } - return m5mols_set_mode(info, REG_PARAMETER); + mutex_unlock(&info->lock); + return ret; } static const struct v4l2_subdev_video_ops m5mols_video_ops = { @@ -773,6 +785,20 @@ static int m5mols_fw_start(struct v4l2_subdev *sd) return ret; } +/* Execute the lens soft-landing algorithm */ +static int m5mols_auto_focus_stop(struct m5mols_info *info) +{ + int ret; + + ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP); + if (!ret) + ret = m5mols_write(&info->sd, AF_MODE, REG_AF_POWEROFF); + if (!ret) + ret = m5mols_busy_wait(&info->sd, SYSTEM_STATUS, REG_AF_IDLE, + 0xff, -1); + return ret; +} + /** * m5mols_s_power - Main sensor power control function * @@ -785,29 +811,26 @@ static int m5mols_s_power(struct v4l2_subdev *sd, int on) struct m5mols_info *info = to_m5mols(sd); int ret; + mutex_lock(&info->lock); + if (on) { ret = m5mols_sensor_power(info, true); if (!ret) ret = m5mols_fw_start(sd); - return ret; - } + } else { + if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) { + ret = m5mols_set_mode(info, REG_MONITOR); + if (!ret) + ret = m5mols_auto_focus_stop(info); + if (ret < 0) + v4l2_warn(sd, "Soft landing lens failed\n"); + } + ret = m5mols_sensor_power(info, false); - if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) { - ret = m5mols_set_mode(info, REG_MONITOR); - if (!ret) - ret = m5mols_write(sd, AF_EXECUTE, REG_AF_STOP); - if (!ret) - ret = m5mols_write(sd, AF_MODE, REG_AF_POWEROFF); - if (!ret) - ret = m5mols_busy_wait(sd, SYSTEM_STATUS, REG_AF_IDLE, - 0xff, -1); - if (ret < 0) - v4l2_warn(sd, "Soft landing lens failed\n"); + info->ctrl_sync = 0; } - ret = m5mols_sensor_power(info, false); - info->ctrl_sync = 0; - + mutex_unlock(&info->lock); return ret; } @@ -912,6 +935,8 @@ static int __devinit m5mols_probe(struct i2c_client *client, sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; init_waitqueue_head(&info->irq_waitq); + mutex_init(&info->lock); + ret = request_irq(client->irq, m5mols_irq_handler, IRQF_TRIGGER_RISING, MODULE_NAME, sd); if (ret) {