aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Wu <josh.wu@atmel.com>2015-03-01 20:52:38 -0500
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-02 17:34:42 -0400
commitf180ebae1ac05805acdb808eb92e63ddbd014934 (patch)
tree2816a1924464c8421cf87ba68a5aa49a0de3ca32
parent0b9508aa030f8119c20fcf64b4b36bc792b59d41 (diff)
[media] media: ov2640: add async probe function
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 <josh.wu@atmel.com> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r--drivers/media/i2c/soc_camera/ov2640.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c
index 1fdce2f6f880..16adbccdfa6c 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,
1068 return -ENOMEM; 1068 return -ENOMEM;
1069 } 1069 }
1070 1070
1071 priv->clk = v4l2_clk_get(&client->dev, "mclk");
1072 if (IS_ERR(priv->clk))
1073 return -EPROBE_DEFER;
1074
1071 v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops); 1075 v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops);
1072 v4l2_ctrl_handler_init(&priv->hdl, 2); 1076 v4l2_ctrl_handler_init(&priv->hdl, 2);
1073 v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops, 1077 v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
@@ -1075,24 +1079,27 @@ static int ov2640_probe(struct i2c_client *client,
1075 v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops, 1079 v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
1076 V4L2_CID_HFLIP, 0, 1, 1, 0); 1080 V4L2_CID_HFLIP, 0, 1, 1, 0);
1077 priv->subdev.ctrl_handler = &priv->hdl; 1081 priv->subdev.ctrl_handler = &priv->hdl;
1078 if (priv->hdl.error) 1082 if (priv->hdl.error) {
1079 return priv->hdl.error; 1083 ret = priv->hdl.error;
1080 1084 goto err_clk;
1081 priv->clk = v4l2_clk_get(&client->dev, "mclk");
1082 if (IS_ERR(priv->clk)) {
1083 ret = PTR_ERR(priv->clk);
1084 goto eclkget;
1085 } 1085 }
1086 1086
1087 ret = ov2640_video_probe(client); 1087 ret = ov2640_video_probe(client);
1088 if (ret) { 1088 if (ret < 0)
1089 v4l2_clk_put(priv->clk); 1089 goto err_videoprobe;
1090eclkget:
1091 v4l2_ctrl_handler_free(&priv->hdl);
1092 } else {
1093 dev_info(&adapter->dev, "OV2640 Probed\n");
1094 }
1095 1090
1091 ret = v4l2_async_register_subdev(&priv->subdev);
1092 if (ret < 0)
1093 goto err_videoprobe;
1094
1095 dev_info(&adapter->dev, "OV2640 Probed\n");
1096
1097 return 0;
1098
1099err_videoprobe:
1100 v4l2_ctrl_handler_free(&priv->hdl);
1101err_clk:
1102 v4l2_clk_put(priv->clk);
1096 return ret; 1103 return ret;
1097} 1104}
1098 1105
@@ -1100,6 +1107,7 @@ static int ov2640_remove(struct i2c_client *client)
1100{ 1107{
1101 struct ov2640_priv *priv = to_ov2640(client); 1108 struct ov2640_priv *priv = to_ov2640(client);
1102 1109
1110 v4l2_async_unregister_subdev(&priv->subdev);
1103 v4l2_clk_put(priv->clk); 1111 v4l2_clk_put(priv->clk);
1104 v4l2_device_unregister_subdev(&priv->subdev); 1112 v4l2_device_unregister_subdev(&priv->subdev);
1105 v4l2_ctrl_handler_free(&priv->hdl); 1113 v4l2_ctrl_handler_free(&priv->hdl);