Commit 2f76e6e8 authored by Martin Kepplinger's avatar Martin Kepplinger
Browse files

hi846: power management and locking fixes

basically this locks larger areas and does away with the autosuspend
delay (that no other camera driver does actually).
parent 0b45b044
Pipeline #67567 passed with stage
in 59 minutes and 40 seconds
......@@ -847,6 +847,9 @@ static int hi846_set_ctrl(struct v4l2_ctrl *ctrl)
int ret = 0;
u32 shutter, frame_len;
if (!pm_runtime_get_if_in_use(&client->dev))
goto out;
/* Propagate change of current control to all related controls */
if (ctrl->id == V4L2_CID_VBLANK) {
/* Update max exposure while meeting expected vblanking */
......@@ -858,14 +861,6 @@ static int hi846_set_ctrl(struct v4l2_ctrl *ctrl)
exposure_max);
}
ret = pm_runtime_get_sync(&client->dev);
if (ret < 0) {
dev_err(&client->dev, "%s: pm_runtime_get failed: %d\n",
__func__, ret);
pm_runtime_put_noidle(&client->dev);
return ret;
}
switch (ctrl->id) {
case V4L2_CID_ANALOGUE_GAIN:
dev_dbg(&client->dev, "%s: V4L2_CID_ANALOGUE_GAIN\n", __func__);
......@@ -921,9 +916,8 @@ static int hi846_set_ctrl(struct v4l2_ctrl *ctrl)
break;
}
pm_runtime_mark_last_busy(&client->dev);
pm_runtime_put_autosuspend(&client->dev);
pm_runtime_put(&client->dev);
out:
return ret;
}
......@@ -1033,8 +1027,6 @@ static int hi846_start_streaming(struct hi846 *hi846)
int ret = 0;
u8 val;
mutex_lock(&hi846->mutex);
if (hi846->nr_lanes == 2)
ret = hi846_write_reg_list(hi846, &hi846_init_regs_list_2lane);
else
......@@ -1105,8 +1097,6 @@ static int hi846_start_streaming(struct hi846 *hi846)
dev_info(&client->dev, "visible pixel width and height is 0\n");
out:
mutex_unlock(&hi846->mutex);
return ret;
}
......@@ -1116,14 +1106,10 @@ static void hi846_stop_streaming(struct hi846 *hi846)
dev_dbg(&client->dev, "%s\n", __func__);
mutex_lock(&hi846->mutex);
if (hi846_write_reg(hi846, HI846_REG_MODE_SELECT, HI846_MODE_STANDBY))
dev_err(&client->dev, "failed to stop stream");
hi846->streaming = 0;
mutex_unlock(&hi846->mutex);
}
static int hi846_set_stream(struct v4l2_subdev *sd, int enable)
......@@ -1137,6 +1123,8 @@ static int hi846_set_stream(struct v4l2_subdev *sd, int enable)
if (hi846->streaming == enable)
return 0;
mutex_lock(&hi846->mutex);
if (enable) {
ret = pm_runtime_get_sync(&client->dev);
if (ret < 0) {
......@@ -1148,16 +1136,16 @@ static int hi846_set_stream(struct v4l2_subdev *sd, int enable)
if (ret) {
enable = 0;
hi846_stop_streaming(hi846);
pm_runtime_mark_last_busy(&client->dev);
pm_runtime_put_autosuspend(&client->dev);
pm_runtime_put(&client->dev);
}
} else {
hi846_stop_streaming(hi846);
pm_runtime_mark_last_busy(&client->dev);
pm_runtime_put_autosuspend(&client->dev);
pm_runtime_put(&client->dev);
}
out:
mutex_unlock(&hi846->mutex);
return ret;
}
......@@ -1262,8 +1250,17 @@ static int hi846_set_format(struct v4l2_subdev *sd,
fmt = &hi846_colour_fmts[0];
}
if (format->which == V4L2_SUBDEV_FORMAT_TRY)
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
*v4l2_subdev_get_try_format(sd, cfg, format->pad) = *mf;
return 0;
}
mutex_lock(&hi846->mutex);
if (hi846->streaming) {
mutex_unlock(&hi846->mutex);
return -EBUSY;
}
hi846->fmt = fmt;
......@@ -1271,7 +1268,8 @@ static int hi846_set_format(struct v4l2_subdev *sd,
ARRAY_SIZE(supported_modes), width,
height, mf->width,
mf->height);
dev_dbg(&client->dev, "%s: found mode: %dx%d\n", __func__, hi846->cur_mode->width, hi846->cur_mode->height);
dev_dbg(&client->dev, "%s: found mode: %dx%d\n", __func__,
hi846->cur_mode->width, hi846->cur_mode->height);
tgt_fps = hi846->cur_mode->fps;
dev_dbg(&client->dev, "%s: target fps: %d\n", __func__, tgt_fps);
......@@ -1298,11 +1296,14 @@ static int hi846_set_format(struct v4l2_subdev *sd,
__v4l2_ctrl_modify_range(hi846->hblank, h_blank, h_blank, 1,
h_blank);
dev_dbg(&client->dev, "Set format w=%d h=%d code=0x%x colorspace=0x%x\n",
dev_dbg(&client->dev, "Set fmt w=%d h=%d code=0x%x colorspace=0x%x\n",
mf->width, mf->height,
fmt->code, fmt->colorspace);
dev_dbg(&client->dev, "--------------------------------------------\n");
mutex_unlock(&hi846->mutex);
return 0;
}
......@@ -1381,13 +1382,24 @@ static int hi846_enum_frame_size(struct v4l2_subdev *sd,
static int hi846_s_power(struct v4l2_subdev *sd, int on)
{
struct hi846 *hi846 = to_hi846(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct device *dev = &client->dev;
int ret = 0;
if (on)
return hi846_resume(dev);
else
return hi846_suspend(dev);
mutex_lock(&hi846->mutex);
if (on) {
ret = hi846_resume(dev);
if (ret)
goto out;
} else {
ret = hi846_suspend(dev);
if (ret)
goto out;
}
out:
mutex_unlock(&hi846->mutex);
return ret;
}
static int hi846_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
......@@ -1552,8 +1564,6 @@ static int hi846_remove(struct i2c_client *client)
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
pm_runtime_put_noidle(&client->dev);
mutex_destroy(&hi846->mutex);
hi846_regulator_disable(hi846);
......@@ -1695,9 +1705,7 @@ static int hi846_probe(struct i2c_client *client)
pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_set_autosuspend_delay(&client->dev, 1000);
pm_runtime_use_autosuspend(&client->dev);
pm_runtime_idle(&client->dev);
hi846->debug_regs = &debug_regstable_list;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment