A set of ov02c10_get_pm_resources() fixes: 1. Reset should only be de-asserted after enabling the regulators and clocks. Request the reset GPIO with GPIOD_OUT_HIGH and on success sleep for 1 ms to ensure that it is asserted for at least 1 ms before ov02c10_power_on() de-asserts it. 2. Use plain devm_regulator_get() for avdd. 3. Add error checking to the ov02c10_get_pm_resources() call in probe(), it may fail with -EPROBE_DEFER. 4. While at it move the v4l2_i2c_subdev_init() call to directly after allocating the ov02c10 struct, it has nothing to do with the ov02c10_get_pm_resources() call. Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx> --- drivers/media/i2c/ov02c10.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c index 38918b1b6a95..a46cacf301a2 100644 --- a/drivers/media/i2c/ov02c10.c +++ b/drivers/media/i2c/ov02c10.c @@ -642,26 +642,23 @@ static int ov02c10_get_pm_resources(struct device *dev) { struct v4l2_subdev *sd = dev_get_drvdata(dev); struct ov02c10 *ov02c10 = to_ov02c10(sd); - int ret; - ov02c10->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + ov02c10->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ov02c10->reset)) return dev_err_probe(dev, PTR_ERR(ov02c10->reset), "failed to get reset gpio\n"); + if (ov02c10->reset) + fsleep(1000); ov02c10->img_clk = devm_clk_get_optional(dev, NULL); if (IS_ERR(ov02c10->img_clk)) return dev_err_probe(dev, PTR_ERR(ov02c10->img_clk), "failed to get imaging clock\n"); - ov02c10->avdd = devm_regulator_get_optional(dev, "avdd"); - if (IS_ERR(ov02c10->avdd)) { - ret = PTR_ERR(ov02c10->avdd); - ov02c10->avdd = NULL; - if (ret != -ENODEV) - return dev_err_probe(dev, ret, - "failed to get avdd regulator\n"); - } + ov02c10->avdd = devm_regulator_get(dev, "avdd"); + if (IS_ERR(ov02c10->avdd)) + return dev_err_probe(dev, PTR_ERR(ov02c10->avdd), + "failed to get avdd regulator\n"); return 0; } @@ -966,13 +963,16 @@ static int ov02c10_probe(struct i2c_client *client) if (!ov02c10) return -ENOMEM; + v4l2_i2c_subdev_init(&ov02c10->sd, client, &ov02c10_subdev_ops); + /* Check HW config */ ret = ov02c10_check_hwcfg(&client->dev, ov02c10); if (ret) return ret; - v4l2_i2c_subdev_init(&ov02c10->sd, client, &ov02c10_subdev_ops); - ov02c10_get_pm_resources(&client->dev); + ret = ov02c10_get_pm_resources(&client->dev); + if (ret) + return ret; ov02c10->regmap = devm_cci_regmap_init_i2c(client, 16); if (IS_ERR(ov02c10->regmap)) -- 2.48.1