@@ -1743,13 +1743,11 @@ static int ccs_start_streaming(struct ccs_sensor *sensor)
unsigned int binning_mode;
int rval;
- mutex_lock(&sensor->mutex);
-
rval = ccs_write(sensor, CSI_DATA_FORMAT,
(sensor->csi_format->width << 8) |
sensor->csi_format->compressed);
if (rval)
- goto out;
+ return rval;
/* Binning configuration */
if (sensor->binning_horizontal == 1 &&
@@ -1762,38 +1760,38 @@ static int ccs_start_streaming(struct ccs_sensor *sensor)
rval = ccs_write(sensor, BINNING_TYPE, binning_type);
if (rval < 0)
- goto out;
+ return rval;
binning_mode = 1;
}
rval = ccs_write(sensor, BINNING_MODE, binning_mode);
if (rval < 0)
- goto out;
+ return rval;
/* Set up PLL */
rval = ccs_pll_configure(sensor);
if (rval)
- goto out;
+ return rval;
/* Analog crop start coordinates */
rval = ccs_write(sensor, X_ADDR_START, sensor->pa_src.left);
if (rval < 0)
- goto out;
+ return rval;
rval = ccs_write(sensor, Y_ADDR_START, sensor->pa_src.top);
if (rval < 0)
- goto out;
+ return rval;
/* Analog crop end coordinates */
rval = ccs_write(sensor, X_ADDR_END,
sensor->pa_src.left + sensor->pa_src.width - 1);
if (rval < 0)
- goto out;
+ return rval;
rval = ccs_write(sensor, Y_ADDR_END,
sensor->pa_src.top + sensor->pa_src.height - 1);
if (rval < 0)
- goto out;
+ return rval;
/*
* Output from pixel array, including blanking, is set using
@@ -1806,22 +1804,22 @@ static int ccs_start_streaming(struct ccs_sensor *sensor)
rval = ccs_write(sensor, DIGITAL_CROP_X_OFFSET,
sensor->scaler_sink.left);
if (rval < 0)
- goto out;
+ return rval;
rval = ccs_write(sensor, DIGITAL_CROP_Y_OFFSET,
sensor->scaler_sink.top);
if (rval < 0)
- goto out;
+ return rval;
rval = ccs_write(sensor, DIGITAL_CROP_IMAGE_WIDTH,
sensor->scaler_sink.width);
if (rval < 0)
- goto out;
+ return rval;
rval = ccs_write(sensor, DIGITAL_CROP_IMAGE_HEIGHT,
sensor->scaler_sink.height);
if (rval < 0)
- goto out;
+ return rval;
}
/* Scaling */
@@ -1829,26 +1827,26 @@ static int ccs_start_streaming(struct ccs_sensor *sensor)
!= CCS_SCALING_CAPABILITY_NONE) {
rval = ccs_write(sensor, SCALING_MODE, sensor->scaling_mode);
if (rval < 0)
- goto out;
+ return rval;
rval = ccs_write(sensor, SCALE_M, sensor->scale_m);
if (rval < 0)
- goto out;
+ return rval;
}
/* Output size from sensor */
rval = ccs_write(sensor, X_OUTPUT_SIZE, sensor->src_src.width);
if (rval < 0)
- goto out;
+ return rval;
rval = ccs_write(sensor, Y_OUTPUT_SIZE, sensor->src_src.height);
if (rval < 0)
- goto out;
+ return rval;
/* Configure embedded data */
if (sensor->csi_format->compressed >= 16) {
rval = ccs_write(sensor, EMB_DATA_CTRL, sensor->emb_data_ctrl);
if (rval < 0)
- goto out;
+ return rval;
}
if (CCS_LIM(sensor, FLASH_MODE_CAPABILITY) &
@@ -1858,21 +1856,16 @@ static int ccs_start_streaming(struct ccs_sensor *sensor)
sensor->hwcfg.strobe_setup->trigger != 0) {
rval = ccs_setup_flash_strobe(sensor);
if (rval)
- goto out;
+ return rval;
}
rval = ccs_call_quirk(sensor, pre_streamon);
if (rval) {
dev_err(&client->dev, "pre_streamon quirks failed\n");
- goto out;
+ return rval;
}
- rval = ccs_write(sensor, MODE_SELECT, CCS_MODE_SELECT_STREAMING);
-
-out:
- mutex_unlock(&sensor->mutex);
-
- return rval;
+ return ccs_write(sensor, MODE_SELECT, CCS_MODE_SELECT_STREAMING);
}
static int ccs_stop_streaming(struct ccs_sensor *sensor)
@@ -1880,17 +1873,14 @@ static int ccs_stop_streaming(struct ccs_sensor *sensor)
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
int rval;
- mutex_lock(&sensor->mutex);
rval = ccs_write(sensor, MODE_SELECT, CCS_MODE_SELECT_SOFTWARE_STANDBY);
if (rval)
- goto out;
+ return rval;
rval = ccs_call_quirk(sensor, post_streamoff);
if (rval)
dev_err(&client->dev, "post_streamoff quirks failed\n");
-out:
- mutex_unlock(&sensor->mutex);
return rval;
}
@@ -1942,7 +1932,9 @@ static int ccs_set_stream(struct v4l2_subdev *subdev, int enable)
return 0;
if (!enable) {
+ mutex_lock(&sensor->mutex);
ccs_stop_streaming(sensor);
+ mutex_unlock(&sensor->mutex);
sensor->streaming = false;
pm_runtime_mark_last_busy(&client->dev);
pm_runtime_put_autosuspend(&client->dev);
@@ -1956,7 +1948,9 @@ static int ccs_set_stream(struct v4l2_subdev *subdev, int enable)
sensor->streaming = true;
+ mutex_lock(&sensor->mutex);
rval = ccs_start_streaming(sensor);
+ mutex_unlock(&sensor->mutex);
if (rval < 0) {
sensor->streaming = false;
pm_runtime_mark_last_busy(&client->dev);
Both ccs_start_streaming() and ccs_stop_streaming() take the mutex for serialising starting and stopping streaming. Move acquiring and releasing the mutex out to the caller, ccs_set_stream(), in order to simplify error handling in both of the functions. Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> --- drivers/media/i2c/ccs/ccs-core.c | 56 ++++++++++++++------------------ 1 file changed, 25 insertions(+), 31 deletions(-)