Skip to content

Commit f66556c

Browse files
jwrdegoedemchehab
authored andcommitted
media: atomisp: Adjust for v4l2_subdev_state handling changes in 6.8
The atomisp driver emulates a standard v4l2 device, which also works for non media-controller aware applications. Part of this requires making try_fmt calls on the sensor when a normal v4l2 app is making try_fmt calls on the /dev/video# mode. With the recent v4l2_subdev_state handling changes in 6.8 this no longer works, fixing this requires 2 changes: 1. The atomisp code was using its own internal v4l2_subdev_pad_config for this. Replace the internal v4l2_subdev_pad_config with allocating a full v4l2_subdev_state for storing the full try_fmt state. 2. The paths actually setting the fmt or crop selection now need to be passed the v4l2_subdev's active state, so that sensor drivers which are using the v4l2_subdev's active state to store their state keep working. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
1 parent ffb635b commit f66556c

File tree

4 files changed

+111
-62
lines changed

4 files changed

+111
-62
lines changed

drivers/staging/media/atomisp/pci/atomisp_cmd.c

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3723,12 +3723,10 @@ void atomisp_get_padding(struct atomisp_device *isp, u32 width, u32 height,
37233723

37243724
static int atomisp_set_crop(struct atomisp_device *isp,
37253725
const struct v4l2_mbus_framefmt *format,
3726+
struct v4l2_subdev_state *sd_state,
37263727
int which)
37273728
{
37283729
struct atomisp_input_subdev *input = &isp->inputs[isp->asd.input_curr];
3729-
struct v4l2_subdev_state pad_state = {
3730-
.pads = &input->pad_cfg,
3731-
};
37323730
struct v4l2_subdev_selection sel = {
37333731
.which = which,
37343732
.target = V4L2_SEL_TGT_CROP,
@@ -3754,7 +3752,7 @@ static int atomisp_set_crop(struct atomisp_device *isp,
37543752
sel.r.left = ((input->native_rect.width - sel.r.width) / 2) & ~1;
37553753
sel.r.top = ((input->native_rect.height - sel.r.height) / 2) & ~1;
37563754

3757-
ret = v4l2_subdev_call(input->camera, pad, set_selection, &pad_state, &sel);
3755+
ret = v4l2_subdev_call(input->camera, pad, set_selection, sd_state, &sel);
37583756
if (ret)
37593757
dev_err(isp->dev, "Error setting crop to %ux%u @%ux%u: %d\n",
37603758
sel.r.width, sel.r.height, sel.r.left, sel.r.top, ret);
@@ -3770,9 +3768,6 @@ int atomisp_try_fmt(struct atomisp_device *isp, struct v4l2_pix_format *f,
37703768
const struct atomisp_format_bridge *fmt, *snr_fmt;
37713769
struct atomisp_sub_device *asd = &isp->asd;
37723770
struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr];
3773-
struct v4l2_subdev_state pad_state = {
3774-
.pads = &input->pad_cfg,
3775-
};
37763771
struct v4l2_subdev_format format = {
37773772
.which = V4L2_SUBDEV_FORMAT_TRY,
37783773
};
@@ -3809,11 +3804,16 @@ int atomisp_try_fmt(struct atomisp_device *isp, struct v4l2_pix_format *f,
38093804
dev_dbg(isp->dev, "try_mbus_fmt: asking for %ux%u\n",
38103805
format.format.width, format.format.height);
38113806

3812-
ret = atomisp_set_crop(isp, &format.format, V4L2_SUBDEV_FORMAT_TRY);
3813-
if (ret)
3814-
return ret;
3807+
v4l2_subdev_lock_state(input->try_sd_state);
3808+
3809+
ret = atomisp_set_crop(isp, &format.format, input->try_sd_state,
3810+
V4L2_SUBDEV_FORMAT_TRY);
3811+
if (ret == 0)
3812+
ret = v4l2_subdev_call(input->camera, pad, set_fmt,
3813+
input->try_sd_state, &format);
3814+
3815+
v4l2_subdev_unlock_state(input->try_sd_state);
38153816

3816-
ret = v4l2_subdev_call(input->camera, pad, set_fmt, &pad_state, &format);
38173817
if (ret)
38183818
return ret;
38193819

@@ -4238,9 +4238,7 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p
42384238
struct atomisp_device *isp = asd->isp;
42394239
struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr];
42404240
const struct atomisp_format_bridge *format;
4241-
struct v4l2_subdev_state pad_state = {
4242-
.pads = &input->pad_cfg,
4243-
};
4241+
struct v4l2_subdev_state *act_sd_state;
42444242
struct v4l2_subdev_format vformat = {
42454243
.which = V4L2_SUBDEV_FORMAT_TRY,
42464244
};
@@ -4268,12 +4266,18 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p
42684266

42694267
/* Disable dvs if resolution can't be supported by sensor */
42704268
if (asd->params.video_dis_en && asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
4271-
ret = atomisp_set_crop(isp, &vformat.format, V4L2_SUBDEV_FORMAT_TRY);
4272-
if (ret)
4273-
return ret;
4269+
v4l2_subdev_lock_state(input->try_sd_state);
4270+
4271+
ret = atomisp_set_crop(isp, &vformat.format, input->try_sd_state,
4272+
V4L2_SUBDEV_FORMAT_TRY);
4273+
if (ret == 0) {
4274+
vformat.which = V4L2_SUBDEV_FORMAT_TRY;
4275+
ret = v4l2_subdev_call(input->camera, pad, set_fmt,
4276+
input->try_sd_state, &vformat);
4277+
}
4278+
4279+
v4l2_subdev_unlock_state(input->try_sd_state);
42744280

4275-
vformat.which = V4L2_SUBDEV_FORMAT_TRY;
4276-
ret = v4l2_subdev_call(input->camera, pad, set_fmt, &pad_state, &vformat);
42774281
if (ret)
42784282
return ret;
42794283

@@ -4291,12 +4295,18 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p
42914295
}
42924296
}
42934297

4294-
ret = atomisp_set_crop(isp, &vformat.format, V4L2_SUBDEV_FORMAT_ACTIVE);
4295-
if (ret)
4296-
return ret;
4298+
act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera);
4299+
4300+
ret = atomisp_set_crop(isp, &vformat.format, act_sd_state,
4301+
V4L2_SUBDEV_FORMAT_ACTIVE);
4302+
if (ret == 0) {
4303+
vformat.which = V4L2_SUBDEV_FORMAT_ACTIVE;
4304+
ret = v4l2_subdev_call(input->camera, pad, set_fmt, act_sd_state, &vformat);
4305+
}
4306+
4307+
if (act_sd_state)
4308+
v4l2_subdev_unlock_state(act_sd_state);
42974309

4298-
vformat.which = V4L2_SUBDEV_FORMAT_ACTIVE;
4299-
ret = v4l2_subdev_call(input->camera, pad, set_fmt, NULL, &vformat);
43004310
if (ret)
43014311
return ret;
43024312

drivers/staging/media/atomisp/pci/atomisp_internal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ struct atomisp_input_subdev {
132132
/* Sensor rects for sensors which support crop */
133133
struct v4l2_rect native_rect;
134134
struct v4l2_rect active_rect;
135-
/* Sensor pad_cfg for which == V4L2_SUBDEV_FORMAT_TRY calls */
136-
struct v4l2_subdev_pad_config pad_cfg;
135+
/* Sensor state for which == V4L2_SUBDEV_FORMAT_TRY calls */
136+
struct v4l2_subdev_state *try_sd_state;
137137

138138
struct v4l2_subdev *motor;
139139

drivers/staging/media/atomisp/pci/atomisp_ioctl.c

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -781,12 +781,20 @@ static int atomisp_enum_framesizes(struct file *file, void *priv,
781781
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
782782
.code = input->code,
783783
};
784+
struct v4l2_subdev_state *act_sd_state;
784785
int ret;
785786

787+
if (!input->camera)
788+
return -EINVAL;
789+
786790
if (input->crop_support)
787791
return atomisp_enum_framesizes_crop(isp, fsize);
788792

789-
ret = v4l2_subdev_call(input->camera, pad, enum_frame_size, NULL, &fse);
793+
act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera);
794+
ret = v4l2_subdev_call(input->camera, pad, enum_frame_size,
795+
act_sd_state, &fse);
796+
if (act_sd_state)
797+
v4l2_subdev_unlock_state(act_sd_state);
790798
if (ret)
791799
return ret;
792800

@@ -803,18 +811,25 @@ static int atomisp_enum_frameintervals(struct file *file, void *priv,
803811
struct video_device *vdev = video_devdata(file);
804812
struct atomisp_device *isp = video_get_drvdata(vdev);
805813
struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
814+
struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr];
806815
struct v4l2_subdev_frame_interval_enum fie = {
807-
.code = atomisp_in_fmt_conv[0].code,
816+
.code = atomisp_in_fmt_conv[0].code,
808817
.index = fival->index,
809818
.width = fival->width,
810819
.height = fival->height,
811820
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
812821
};
822+
struct v4l2_subdev_state *act_sd_state;
813823
int ret;
814824

815-
ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
816-
pad, enum_frame_interval, NULL,
817-
&fie);
825+
if (!input->camera)
826+
return -EINVAL;
827+
828+
act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera);
829+
ret = v4l2_subdev_call(input->camera, pad, enum_frame_interval,
830+
act_sd_state, &fie);
831+
if (act_sd_state)
832+
v4l2_subdev_unlock_state(act_sd_state);
818833
if (ret)
819834
return ret;
820835

@@ -830,30 +845,25 @@ static int atomisp_enum_fmt_cap(struct file *file, void *fh,
830845
struct video_device *vdev = video_devdata(file);
831846
struct atomisp_device *isp = video_get_drvdata(vdev);
832847
struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
848+
struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr];
833849
struct v4l2_subdev_mbus_code_enum code = {
834850
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
835851
};
836852
const struct atomisp_format_bridge *format;
837-
struct v4l2_subdev *camera;
853+
struct v4l2_subdev_state *act_sd_state;
838854
unsigned int i, fi = 0;
839-
int rval;
855+
int ret;
840856

841-
camera = isp->inputs[asd->input_curr].camera;
842-
if(!camera) {
843-
dev_err(isp->dev, "%s(): camera is NULL, device is %s\n",
844-
__func__, vdev->name);
857+
if (!input->camera)
845858
return -EINVAL;
846-
}
847859

848-
rval = v4l2_subdev_call(camera, pad, enum_mbus_code, NULL, &code);
849-
if (rval == -ENOIOCTLCMD) {
850-
dev_warn(isp->dev,
851-
"enum_mbus_code pad op not supported by %s. Please fix your sensor driver!\n",
852-
camera->name);
853-
}
854-
855-
if (rval)
856-
return rval;
860+
act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera);
861+
ret = v4l2_subdev_call(input->camera, pad, enum_mbus_code,
862+
act_sd_state, &code);
863+
if (act_sd_state)
864+
v4l2_subdev_unlock_state(act_sd_state);
865+
if (ret)
866+
return ret;
857867

858868
for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) {
859869
format = &atomisp_output_fmts[i];

drivers/staging/media/atomisp/pci/atomisp_v4l2.c

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,9 @@ static void atomisp_unregister_entities(struct atomisp_device *isp)
862862
v4l2_device_unregister(&isp->v4l2_dev);
863863
media_device_unregister(&isp->media_dev);
864864
media_device_cleanup(&isp->media_dev);
865+
866+
for (i = 0; i < isp->input_cnt; i++)
867+
__v4l2_subdev_state_free(isp->inputs[i].try_sd_state);
865868
}
866869

867870
static int atomisp_register_entities(struct atomisp_device *isp)
@@ -933,32 +936,49 @@ static int atomisp_register_entities(struct atomisp_device *isp)
933936

934937
static void atomisp_init_sensor(struct atomisp_input_subdev *input)
935938
{
939+
static struct lock_class_key try_sd_state_key;
936940
struct v4l2_subdev_mbus_code_enum mbus_code_enum = { };
937941
struct v4l2_subdev_frame_size_enum fse = { };
938-
struct v4l2_subdev_state sd_state = {
939-
.pads = &input->pad_cfg,
940-
};
941942
struct v4l2_subdev_selection sel = { };
943+
struct v4l2_subdev_state *try_sd_state, *act_sd_state;
942944
int i, err;
943945

946+
/*
947+
* FIXME: Drivers are not supposed to use __v4l2_subdev_state_alloc()
948+
* but atomisp needs this for try_fmt on its /dev/video# node since
949+
* it emulates a normal v4l2 device there, passing through try_fmt /
950+
* set_fmt to the sensor.
951+
*/
952+
try_sd_state = __v4l2_subdev_state_alloc(input->camera,
953+
"atomisp:try_sd_state->lock", &try_sd_state_key);
954+
if (IS_ERR(try_sd_state))
955+
return;
956+
957+
input->try_sd_state = try_sd_state;
958+
959+
act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera);
960+
944961
mbus_code_enum.which = V4L2_SUBDEV_FORMAT_ACTIVE;
945-
err = v4l2_subdev_call(input->camera, pad, enum_mbus_code, NULL, &mbus_code_enum);
962+
err = v4l2_subdev_call(input->camera, pad, enum_mbus_code,
963+
act_sd_state, &mbus_code_enum);
946964
if (!err)
947965
input->code = mbus_code_enum.code;
948966

949967
sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
950968
sel.target = V4L2_SEL_TGT_NATIVE_SIZE;
951-
err = v4l2_subdev_call(input->camera, pad, get_selection, NULL, &sel);
969+
err = v4l2_subdev_call(input->camera, pad, get_selection,
970+
act_sd_state, &sel);
952971
if (err)
953-
return;
972+
goto unlock_act_sd_state;
954973

955974
input->native_rect = sel.r;
956975

957976
sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
958977
sel.target = V4L2_SEL_TGT_CROP_DEFAULT;
959-
err = v4l2_subdev_call(input->camera, pad, get_selection, NULL, &sel);
978+
err = v4l2_subdev_call(input->camera, pad, get_selection,
979+
act_sd_state, &sel);
960980
if (err)
961-
return;
981+
goto unlock_act_sd_state;
962982

963983
input->active_rect = sel.r;
964984

@@ -973,7 +993,8 @@ static void atomisp_init_sensor(struct atomisp_input_subdev *input)
973993
fse.code = input->code;
974994
fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
975995

976-
err = v4l2_subdev_call(input->camera, pad, enum_frame_size, NULL, &fse);
996+
err = v4l2_subdev_call(input->camera, pad, enum_frame_size,
997+
act_sd_state, &fse);
977998
if (err)
978999
break;
9791000

@@ -989,29 +1010,37 @@ static void atomisp_init_sensor(struct atomisp_input_subdev *input)
9891010
* for padding, set the crop rect to cover the entire sensor instead
9901011
* of only the default active area.
9911012
*
992-
* Do this for both try and active formats since the try_crop rect in
993-
* pad_cfg may influence (clamp) future try_fmt calls with which == try.
1013+
* Do this for both try and active formats since the crop rect in
1014+
* try_sd_state may influence (clamp size) in calls with which == try.
9941015
*/
9951016
sel.which = V4L2_SUBDEV_FORMAT_TRY;
9961017
sel.target = V4L2_SEL_TGT_CROP;
9971018
sel.r = input->native_rect;
998-
err = v4l2_subdev_call(input->camera, pad, set_selection, &sd_state, &sel);
1019+
v4l2_subdev_lock_state(input->try_sd_state);
1020+
err = v4l2_subdev_call(input->camera, pad, set_selection,
1021+
input->try_sd_state, &sel);
1022+
v4l2_subdev_unlock_state(input->try_sd_state);
9991023
if (err)
1000-
return;
1024+
goto unlock_act_sd_state;
10011025

10021026
sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
10031027
sel.target = V4L2_SEL_TGT_CROP;
10041028
sel.r = input->native_rect;
1005-
err = v4l2_subdev_call(input->camera, pad, set_selection, NULL, &sel);
1029+
err = v4l2_subdev_call(input->camera, pad, set_selection,
1030+
act_sd_state, &sel);
10061031
if (err)
1007-
return;
1032+
goto unlock_act_sd_state;
10081033

10091034
dev_info(input->camera->dev, "Supports crop native %dx%d active %dx%d binning %d\n",
10101035
input->native_rect.width, input->native_rect.height,
10111036
input->active_rect.width, input->active_rect.height,
10121037
input->binning_support);
10131038

10141039
input->crop_support = true;
1040+
1041+
unlock_act_sd_state:
1042+
if (act_sd_state)
1043+
v4l2_subdev_unlock_state(act_sd_state);
10151044
}
10161045

10171046
int atomisp_register_device_nodes(struct atomisp_device *isp)

0 commit comments

Comments
 (0)