diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c index 5b909a856128..c6d53c3d55ca 100644 --- a/drivers/media/i2c/ov8865.c +++ b/drivers/media/i2c/ov8865.c @@ -2609,7 +2609,7 @@ static int ov8865_s_stream(struct v4l2_subdev *subdev, int enable) { struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev); struct ov8865_state *state = &sensor->state; - int ret; + int ret = 0; if (enable) { ret = pm_runtime_resume_and_get(sensor->dev); @@ -2618,7 +2618,23 @@ static int ov8865_s_stream(struct v4l2_subdev *subdev, int enable) } mutex_lock(&sensor->mutex); - ret = ov8865_sw_standby(sensor, !enable); + + /* + * The sensor may have been kept powered by something else (e.g. the + * VCM's runtime PM device link on IPU3 platforms), in which case + * runtime resume did not run and the hardware may still be + * configured for a previous mode. Always program the negotiated + * configuration on stream start. + */ + if (enable) { + ret = ov8865_sensor_init(sensor); + if (!ret) + ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); + } + + if (!ret) + ret = ov8865_sw_standby(sensor, !enable); + mutex_unlock(&sensor->mutex); if (ret || !enable) @@ -2914,15 +2930,15 @@ static int ov8865_resume(struct device *dev) if (ret) goto complete; - ret = ov8865_sensor_init(sensor); - if (ret) - goto error_power; - - ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); - if (ret) - goto error_power; - if (state->streaming) { + ret = ov8865_sensor_init(sensor); + if (ret) + goto error_power; + + ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); + if (ret) + goto error_power; + ret = ov8865_sw_standby(sensor, false); if (ret) goto error_power;