From patchwork Mon Mar 2 01:52:38 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josh Wu X-Patchwork-Id: 28450 X-Patchwork-Delegate: g.liakhovetski@gmx.de Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1YSFVj-0002D8-VE; Mon, 02 Mar 2015 02:51:07 +0100 X-tubIT-Incoming-IP: 209.132.180.67 Received: from vger.kernel.org ([209.132.180.67]) by mail.tu-berlin.de (exim-4.72/mailfrontend-5) with esmtp id 1YSFVh-0000u2-8m; Mon, 02 Mar 2015 02:51:07 +0100 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753091AbbCBBvD (ORCPT + 1 other); Sun, 1 Mar 2015 20:51:03 -0500 Received: from eusmtp01.atmel.com ([212.144.249.242]:21301 "EHLO eusmtp01.atmel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752178AbbCBBvB (ORCPT ); Sun, 1 Mar 2015 20:51:01 -0500 Received: from apsmtp01.atmel.com (10.168.254.30) by eusmtp01.atmel.com (10.161.101.30) with Microsoft SMTP Server id 14.2.347.0; Mon, 2 Mar 2015 02:50:58 +0100 Received: from melon.corp.atmel.com (10.168.254.13) by apsmtp01.corp.atmel.com (10.168.254.30) with Microsoft SMTP Server id 14.2.347.0; Mon, 2 Mar 2015 09:54:56 +0800 From: Josh Wu To: CC: , , , , Josh Wu Subject: [PATCH v5 2/4][resend] media: ov2640: add async probe function Date: Mon, 2 Mar 2015 09:52:38 +0800 Message-ID: <1425261158-14603-1-git-send-email-josh.wu@atmel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-PMX-Version: 6.0.0.2142326, Antispam-Engine: 2.7.2.2107409, Antispam-Data: 2015.3.2.14219 X-PMX-Spam: Gauge=IIIIIIIII, Probability=9%, Report=' MULTIPLE_RCPTS 0.1, HTML_00_01 0.05, HTML_00_10 0.05, MSGID_ADDED_BY_MTA 0.05, BODYTEXTP_SIZE_3000_LESS 0, BODY_SIZE_2000_2999 0, BODY_SIZE_5000_LESS 0, BODY_SIZE_7000_LESS 0, REFERENCES 0, URI_ENDS_IN_HTML 0, __ANY_URI 0, __CP_URI_IN_BODY 0, __CT 0, __CT_TEXT_PLAIN 0, __DATE_TZ_HK 0, __HAS_FROM 0, __HAS_MSGID 0, __HAS_X_MAILER 0, __HAS_X_MAILING_LIST 0, __IN_REP_TO 0, __MIME_TEXT_ONLY 0, __MIME_VERSION 0, __MULTIPLE_RCPTS_CC_X2 0, __REFERENCES 0, __SANE_MSGID 0, __SUBJ_ALPHA_END 0, __TO_MALFORMED_2 0, __TO_NO_NAME 0, __URI_NO_WWW 0, __URI_NS ' In async probe, there is a case that ov2640 is probed before the host device which provided 'mclk'. To support this async probe, we will get 'mclk' at first in the probe(), if failed it will return -EPROBE_DEFER. That will let ov2640 wait for the host device probed. Signed-off-by: Josh Wu --- Changes in v5 resend: - refine the error handling flow according to Guennadi's comment. Changes in v5: - don't change the ov2640_s_power() code. - will get 'mclk' at the beginning of ov2640_probe(). drivers/media/i2c/soc_camera/ov2640.c | 36 +++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c index 1fdce2f..16adbcc 100644 --- a/drivers/media/i2c/soc_camera/ov2640.c +++ b/drivers/media/i2c/soc_camera/ov2640.c @@ -1068,6 +1068,10 @@ static int ov2640_probe(struct i2c_client *client, return -ENOMEM; } + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) + return -EPROBE_DEFER; + v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops); v4l2_ctrl_handler_init(&priv->hdl, 2); v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops, @@ -1075,24 +1079,27 @@ static int ov2640_probe(struct i2c_client *client, v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); priv->subdev.ctrl_handler = &priv->hdl; - if (priv->hdl.error) - return priv->hdl.error; - - priv->clk = v4l2_clk_get(&client->dev, "mclk"); - if (IS_ERR(priv->clk)) { - ret = PTR_ERR(priv->clk); - goto eclkget; + if (priv->hdl.error) { + ret = priv->hdl.error; + goto err_clk; } ret = ov2640_video_probe(client); - if (ret) { - v4l2_clk_put(priv->clk); -eclkget: - v4l2_ctrl_handler_free(&priv->hdl); - } else { - dev_info(&adapter->dev, "OV2640 Probed\n"); - } + if (ret < 0) + goto err_videoprobe; + ret = v4l2_async_register_subdev(&priv->subdev); + if (ret < 0) + goto err_videoprobe; + + dev_info(&adapter->dev, "OV2640 Probed\n"); + + return 0; + +err_videoprobe: + v4l2_ctrl_handler_free(&priv->hdl); +err_clk: + v4l2_clk_put(priv->clk); return ret; } @@ -1100,6 +1107,7 @@ static int ov2640_remove(struct i2c_client *client) { struct ov2640_priv *priv = to_ov2640(client); + v4l2_async_unregister_subdev(&priv->subdev); v4l2_clk_put(priv->clk); v4l2_device_unregister_subdev(&priv->subdev); v4l2_ctrl_handler_free(&priv->hdl);