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,
        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;
 }
 
 {
        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);