diff options
author | Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 2021-06-10 16:55:58 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 2021-06-17 10:01:27 +0200 |
commit | 0d346d2a6f54f06f36b224fd27cd6eafe8c83be9 (patch) | |
tree | eacbf2d204719794c200ee1b062f09d07ad8ddd1 /drivers/media/i2c/ccs | |
parent | media: venus: hfi_msgs.h: Replace one-element arrays with flexible-array members (diff) | |
download | linux-0d346d2a6f54f06f36b224fd27cd6eafe8c83be9.tar.xz linux-0d346d2a6f54f06f36b224fd27cd6eafe8c83be9.zip |
media: v4l2-subdev: add subdev-wide state struct
We have 'struct v4l2_subdev_pad_config' which contains configuration for
a single pad used for the TRY functionality, and an array of those
structs is passed to various v4l2_subdev_pad_ops.
I was working on subdev internal routing between pads, and realized that
there's no way to add TRY functionality for routes, which is not pad
specific configuration. Adding a separate struct for try-route config
wouldn't work either, as e.g. set-fmt needs to know the try-route
configuration to propagate the settings.
This patch adds a new struct, 'struct v4l2_subdev_state' (which at the
moment only contains the v4l2_subdev_pad_config array) and the new
struct is used in most of the places where v4l2_subdev_pad_config was
used. All v4l2_subdev_pad_ops functions taking v4l2_subdev_pad_config
are changed to instead take v4l2_subdev_state.
The changes to drivers/media/v4l2-core/v4l2-subdev.c and
include/media/v4l2-subdev.h were written by hand, and all the driver
changes were done with the semantic patch below. The spatch needs to be
applied to a select list of directories. I used the following shell
commands to apply the spatch:
dirs="drivers/media/i2c drivers/media/platform drivers/media/usb drivers/media/test-drivers/vimc drivers/media/pci drivers/staging/media"
for dir in $dirs; do spatch -j8 --dir --include-headers --no-show-diff --in-place --sp-file v4l2-subdev-state.cocci $dir; done
Note that Coccinelle chokes on a few drivers (gcc extensions?). With
minor changes we can make Coccinelle run fine, and these changes can be
reverted after spatch. The diff for these changes is:
For drivers/media/i2c/s5k5baf.c:
@@ -1481,7 +1481,7 @@ static int s5k5baf_set_selection(struct v4l2_subdev *sd,
&s5k5baf_cis_rect,
v4l2_subdev_get_try_crop(sd, cfg, PAD_CIS),
v4l2_subdev_get_try_compose(sd, cfg, PAD_CIS),
- v4l2_subdev_get_try_crop(sd, cfg, PAD_OUT)
+ v4l2_subdev_get_try_crop(sd, cfg, PAD_OUT),
};
s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
return 0;
For drivers/media/platform/s3c-camif/camif-capture.c:
@@ -1230,7 +1230,7 @@ static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd,
*mf = camif->mbus_fmt;
break;
- case CAMIF_SD_PAD_SOURCE_C...CAMIF_SD_PAD_SOURCE_P:
+ case CAMIF_SD_PAD_SOURCE_C:
/* crop rectangle at camera interface input */
mf->width = camif->camif_crop.width;
mf->height = camif->camif_crop.height;
@@ -1332,7 +1332,7 @@ static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd,
}
break;
- case CAMIF_SD_PAD_SOURCE_C...CAMIF_SD_PAD_SOURCE_P:
+ case CAMIF_SD_PAD_SOURCE_C:
/* Pixel format can be only changed on the sink pad. */
mf->code = camif->mbus_fmt.code;
mf->width = crop->width;
The semantic patch is:
// <smpl>
// Change function parameter
@@
identifier func;
identifier cfg;
@@
func(...,
- struct v4l2_subdev_pad_config *cfg
+ struct v4l2_subdev_state *sd_state
, ...)
{
<...
- cfg
+ sd_state
...>
}
// Change function declaration parameter
@@
identifier func;
identifier cfg;
type T;
@@
T func(...,
- struct v4l2_subdev_pad_config *cfg
+ struct v4l2_subdev_state *sd_state
, ...);
// Change function return value
@@
identifier func;
@@
- struct v4l2_subdev_pad_config
+ struct v4l2_subdev_state
*func(...)
{
...
}
// Change function declaration return value
@@
identifier func;
@@
- struct v4l2_subdev_pad_config
+ struct v4l2_subdev_state
*func(...);
// Some drivers pass a local pad_cfg for a single pad to a called function. Wrap it
// inside a pad_state.
@@
identifier func;
identifier pad_cfg;
@@
func(...)
{
...
struct v4l2_subdev_pad_config pad_cfg;
+ struct v4l2_subdev_state pad_state = { .pads = &pad_cfg };
<+...
(
v4l2_subdev_call
|
sensor_call
|
isi_try_fse
|
isc_try_fse
|
saa_call_all
)
(...,
- &pad_cfg
+ &pad_state
,...)
...+>
}
// If the function uses fields from pad_config, access via state->pads
@@
identifier func;
identifier state;
@@
func(...,
struct v4l2_subdev_state *state
, ...)
{
<...
(
- state->try_fmt
+ state->pads->try_fmt
|
- state->try_crop
+ state->pads->try_crop
|
- state->try_compose
+ state->pads->try_compose
)
...>
}
// If the function accesses the filehandle, use fh->state instead
@@
struct v4l2_subdev_fh *fh;
@@
- fh->pad
+ fh->state
@@
struct v4l2_subdev_fh fh;
@@
- fh.pad
+ fh.state
// Start of vsp1 specific
@@
@@
struct vsp1_entity {
...
- struct v4l2_subdev_pad_config *config;
+ struct v4l2_subdev_state *config;
...
};
@@
symbol entity;
@@
vsp1_entity_init(...)
{
...
entity->config =
- v4l2_subdev_alloc_pad_config
+ v4l2_subdev_alloc_state
(&entity->subdev);
...
}
@@
symbol entity;
@@
vsp1_entity_destroy(...)
{
...
- v4l2_subdev_free_pad_config
+ v4l2_subdev_free_state
(entity->config);
...
}
@exists@
identifier func =~ "(^vsp1.*)|(hsit_set_format)|(sru_enum_frame_size)|(sru_set_format)|(uif_get_selection)|(uif_set_selection)|(uds_enum_frame_size)|(uds_set_format)|(brx_set_format)|(brx_get_selection)|(histo_get_selection)|(histo_set_selection)|(brx_set_selection)";
symbol config;
@@
func(...) {
...
- struct v4l2_subdev_pad_config *config;
+ struct v4l2_subdev_state *config;
...
}
// End of vsp1 specific
// Start of rcar specific
@@
identifier sd;
identifier pad_cfg;
@@
rvin_try_format(...)
{
...
- struct v4l2_subdev_pad_config *pad_cfg;
+ struct v4l2_subdev_state *sd_state;
...
- pad_cfg = v4l2_subdev_alloc_pad_config(sd);
+ sd_state = v4l2_subdev_alloc_state(sd);
<...
- pad_cfg
+ sd_state
...>
- v4l2_subdev_free_pad_config(pad_cfg);
+ v4l2_subdev_free_state(sd_state);
...
}
// End of rcar specific
// Start of rockchip specific
@@
identifier func =~ "(rkisp1_rsz_get_pad_fmt)|(rkisp1_rsz_get_pad_crop)|(rkisp1_rsz_register)";
symbol rsz;
symbol pad_cfg;
@@
func(...)
{
+ struct v4l2_subdev_state state = { .pads = rsz->pad_cfg };
...
- rsz->pad_cfg
+ &state
...
}
@@
identifier func =~ "(rkisp1_isp_get_pad_fmt)|(rkisp1_isp_get_pad_crop)";
symbol isp;
symbol pad_cfg;
@@
func(...)
{
+ struct v4l2_subdev_state state = { .pads = isp->pad_cfg };
...
- isp->pad_cfg
+ &state
...
}
@@
symbol rkisp1;
symbol isp;
symbol pad_cfg;
@@
rkisp1_isp_register(...)
{
+ struct v4l2_subdev_state state = { .pads = rkisp1->isp.pad_cfg };
...
- rkisp1->isp.pad_cfg
+ &state
...
}
// End of rockchip specific
// Start of tegra-video specific
@@
identifier sd;
identifier pad_cfg;
@@
__tegra_channel_try_format(...)
{
...
- struct v4l2_subdev_pad_config *pad_cfg;
+ struct v4l2_subdev_state *sd_state;
...
- pad_cfg = v4l2_subdev_alloc_pad_config(sd);
+ sd_state = v4l2_subdev_alloc_state(sd);
<...
- pad_cfg
+ sd_state
...>
- v4l2_subdev_free_pad_config(pad_cfg);
+ v4l2_subdev_free_state(sd_state);
...
}
@@
identifier sd_state;
@@
__tegra_channel_try_format(...)
{
...
struct v4l2_subdev_state *sd_state;
<...
- sd_state->try_crop
+ sd_state->pads->try_crop
...>
}
// End of tegra-video specific
// </smpl>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/media/i2c/ccs')
-rw-r--r-- | drivers/media/i2c/ccs/ccs-core.c | 84 |
1 files changed, 44 insertions, 40 deletions
diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index a349189a38db..a9403a227c6b 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -1944,7 +1944,7 @@ static int ccs_set_stream(struct v4l2_subdev *subdev, int enable) } static int ccs_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct i2c_client *client = v4l2_get_subdevdata(subdev); @@ -1997,13 +1997,13 @@ static u32 __ccs_get_mbus_code(struct v4l2_subdev *subdev, unsigned int pad) } static int __ccs_get_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ccs_subdev *ssd = to_ccs_subdev(subdev); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - fmt->format = *v4l2_subdev_get_try_format(subdev, cfg, + fmt->format = *v4l2_subdev_get_try_format(subdev, sd_state, fmt->pad); } else { struct v4l2_rect *r; @@ -2023,21 +2023,21 @@ static int __ccs_get_format(struct v4l2_subdev *subdev, } static int ccs_get_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); int rval; mutex_lock(&sensor->mutex); - rval = __ccs_get_format(subdev, cfg, fmt); + rval = __ccs_get_format(subdev, sd_state, fmt); mutex_unlock(&sensor->mutex); return rval; } static void ccs_get_crop_compose(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_rect **crops, struct v4l2_rect **comps, int which) { @@ -2054,24 +2054,25 @@ static void ccs_get_crop_compose(struct v4l2_subdev *subdev, if (crops) { for (i = 0; i < subdev->entity.num_pads; i++) crops[i] = v4l2_subdev_get_try_crop(subdev, - cfg, i); + sd_state, + i); } if (comps) - *comps = v4l2_subdev_get_try_compose(subdev, cfg, + *comps = v4l2_subdev_get_try_compose(subdev, sd_state, CCS_PAD_SINK); } } /* Changes require propagation only on sink pad. */ static void ccs_propagate(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, int which, + struct v4l2_subdev_state *sd_state, int which, int target) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); struct ccs_subdev *ssd = to_ccs_subdev(subdev); struct v4l2_rect *comp, *crops[CCS_PADS]; - ccs_get_crop_compose(subdev, cfg, crops, &comp, which); + ccs_get_crop_compose(subdev, sd_state, crops, &comp, which); switch (target) { case V4L2_SEL_TGT_CROP: @@ -2111,7 +2112,7 @@ static const struct ccs_csi_data_format } static int ccs_set_format_source(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); @@ -2122,7 +2123,7 @@ static int ccs_set_format_source(struct v4l2_subdev *subdev, unsigned int i; int rval; - rval = __ccs_get_format(subdev, cfg, fmt); + rval = __ccs_get_format(subdev, sd_state, fmt); if (rval) return rval; @@ -2164,7 +2165,7 @@ static int ccs_set_format_source(struct v4l2_subdev *subdev, } static int ccs_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); @@ -2176,7 +2177,7 @@ static int ccs_set_format(struct v4l2_subdev *subdev, if (fmt->pad == ssd->source_pad) { int rval; - rval = ccs_set_format_source(subdev, cfg, fmt); + rval = ccs_set_format_source(subdev, sd_state, fmt); mutex_unlock(&sensor->mutex); @@ -2198,7 +2199,7 @@ static int ccs_set_format(struct v4l2_subdev *subdev, CCS_LIM(sensor, MIN_Y_OUTPUT_SIZE), CCS_LIM(sensor, MAX_Y_OUTPUT_SIZE)); - ccs_get_crop_compose(subdev, cfg, crops, NULL, fmt->which); + ccs_get_crop_compose(subdev, sd_state, crops, NULL, fmt->which); crops[ssd->sink_pad]->left = 0; crops[ssd->sink_pad]->top = 0; @@ -2206,7 +2207,7 @@ static int ccs_set_format(struct v4l2_subdev *subdev, crops[ssd->sink_pad]->height = fmt->format.height; if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) ssd->sink_fmt = *crops[ssd->sink_pad]; - ccs_propagate(subdev, cfg, fmt->which, V4L2_SEL_TGT_CROP); + ccs_propagate(subdev, sd_state, fmt->which, V4L2_SEL_TGT_CROP); mutex_unlock(&sensor->mutex); @@ -2258,7 +2259,7 @@ static int scaling_goodness(struct v4l2_subdev *subdev, int w, int ask_w, } static void ccs_set_compose_binner(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel, struct v4l2_rect **crops, struct v4l2_rect *comp) @@ -2306,7 +2307,7 @@ static void ccs_set_compose_binner(struct v4l2_subdev *subdev, * result. */ static void ccs_set_compose_scaler(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel, struct v4l2_rect **crops, struct v4l2_rect *comp) @@ -2421,25 +2422,25 @@ static void ccs_set_compose_scaler(struct v4l2_subdev *subdev, } /* We're only called on source pads. This function sets scaling. */ static int ccs_set_compose(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); struct ccs_subdev *ssd = to_ccs_subdev(subdev); struct v4l2_rect *comp, *crops[CCS_PADS]; - ccs_get_crop_compose(subdev, cfg, crops, &comp, sel->which); + ccs_get_crop_compose(subdev, sd_state, crops, &comp, sel->which); sel->r.top = 0; sel->r.left = 0; if (ssd == sensor->binner) - ccs_set_compose_binner(subdev, cfg, sel, crops, comp); + ccs_set_compose_binner(subdev, sd_state, sel, crops, comp); else - ccs_set_compose_scaler(subdev, cfg, sel, crops, comp); + ccs_set_compose_scaler(subdev, sd_state, sel, crops, comp); *comp = sel->r; - ccs_propagate(subdev, cfg, sel->which, V4L2_SEL_TGT_COMPOSE); + ccs_propagate(subdev, sd_state, sel->which, V4L2_SEL_TGT_COMPOSE); if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) return ccs_pll_blanking_update(sensor); @@ -2486,7 +2487,7 @@ static int __ccs_sel_supported(struct v4l2_subdev *subdev, } static int ccs_set_crop(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); @@ -2494,7 +2495,7 @@ static int ccs_set_crop(struct v4l2_subdev *subdev, struct v4l2_rect *src_size, *crops[CCS_PADS]; struct v4l2_rect _r; - ccs_get_crop_compose(subdev, cfg, crops, NULL, sel->which); + ccs_get_crop_compose(subdev, sd_state, crops, NULL, sel->which); if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { if (sel->pad == ssd->sink_pad) @@ -2505,16 +2506,18 @@ static int ccs_set_crop(struct v4l2_subdev *subdev, if (sel->pad == ssd->sink_pad) { _r.left = 0; _r.top = 0; - _r.width = v4l2_subdev_get_try_format(subdev, cfg, + _r.width = v4l2_subdev_get_try_format(subdev, + sd_state, sel->pad) ->width; - _r.height = v4l2_subdev_get_try_format(subdev, cfg, + _r.height = v4l2_subdev_get_try_format(subdev, + sd_state, sel->pad) ->height; src_size = &_r; } else { src_size = v4l2_subdev_get_try_compose( - subdev, cfg, ssd->sink_pad); + subdev, sd_state, ssd->sink_pad); } } @@ -2532,7 +2535,7 @@ static int ccs_set_crop(struct v4l2_subdev *subdev, *crops[sel->pad] = sel->r; if (ssd != sensor->pixel_array && sel->pad == CCS_PAD_SINK) - ccs_propagate(subdev, cfg, sel->which, V4L2_SEL_TGT_CROP); + ccs_propagate(subdev, sd_state, sel->which, V4L2_SEL_TGT_CROP); return 0; } @@ -2546,7 +2549,7 @@ static void ccs_get_native_size(struct ccs_subdev *ssd, struct v4l2_rect *r) } static int __ccs_get_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); @@ -2559,13 +2562,14 @@ static int __ccs_get_selection(struct v4l2_subdev *subdev, if (ret) return ret; - ccs_get_crop_compose(subdev, cfg, crops, &comp, sel->which); + ccs_get_crop_compose(subdev, sd_state, crops, &comp, sel->which); if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { sink_fmt = ssd->sink_fmt; } else { struct v4l2_mbus_framefmt *fmt = - v4l2_subdev_get_try_format(subdev, cfg, ssd->sink_pad); + v4l2_subdev_get_try_format(subdev, sd_state, + ssd->sink_pad); sink_fmt.left = 0; sink_fmt.top = 0; @@ -2596,21 +2600,21 @@ static int __ccs_get_selection(struct v4l2_subdev *subdev, } static int ccs_get_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); int rval; mutex_lock(&sensor->mutex); - rval = __ccs_get_selection(subdev, cfg, sel); + rval = __ccs_get_selection(subdev, sd_state, sel); mutex_unlock(&sensor->mutex); return rval; } static int ccs_set_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); @@ -2634,10 +2638,10 @@ static int ccs_set_selection(struct v4l2_subdev *subdev, switch (sel->target) { case V4L2_SEL_TGT_CROP: - ret = ccs_set_crop(subdev, cfg, sel); + ret = ccs_set_crop(subdev, sd_state, sel); break; case V4L2_SEL_TGT_COMPOSE: - ret = ccs_set_compose(subdev, cfg, sel); + ret = ccs_set_compose(subdev, sd_state, sel); break; default: ret = -EINVAL; @@ -3028,9 +3032,9 @@ static int ccs_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) for (i = 0; i < ssd->npads; i++) { struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, fh->pad, i); + v4l2_subdev_get_try_format(sd, fh->state, i); struct v4l2_rect *try_crop = - v4l2_subdev_get_try_crop(sd, fh->pad, i); + v4l2_subdev_get_try_crop(sd, fh->state, i); struct v4l2_rect *try_comp; ccs_get_native_size(ssd, try_crop); @@ -3043,7 +3047,7 @@ static int ccs_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) if (ssd != sensor->pixel_array) continue; - try_comp = v4l2_subdev_get_try_compose(sd, fh->pad, i); + try_comp = v4l2_subdev_get_try_compose(sd, fh->state, i); *try_comp = *try_crop; } |