mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
media: ivsc: csi: Make use of sub-device state
The MEI CSI driver was using sub-device state but still maintained its own format information and did its own locking. Rely on sub-device state instead. This also fixes a circular locking problem during link validation. Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
This commit is contained in:
parent
48f5fd8967
commit
7b61650b3c
@ -128,7 +128,6 @@ struct mei_csi {
|
||||
int streaming;
|
||||
|
||||
struct media_pad pads[CSI_NUM_PADS];
|
||||
struct v4l2_mbus_framefmt format_mbus[CSI_NUM_PADS];
|
||||
|
||||
/* number of data lanes used on the CSI-2 link */
|
||||
u32 nr_of_lanes;
|
||||
@ -329,58 +328,17 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct v4l2_mbus_framefmt *
|
||||
mei_csi_get_pad_format(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
unsigned int pad, u32 which)
|
||||
{
|
||||
struct mei_csi *csi = sd_to_csi(sd);
|
||||
|
||||
switch (which) {
|
||||
case V4L2_SUBDEV_FORMAT_TRY:
|
||||
return v4l2_subdev_state_get_format(sd_state, pad);
|
||||
case V4L2_SUBDEV_FORMAT_ACTIVE:
|
||||
return &csi->format_mbus[pad];
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int mei_csi_init_state(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state)
|
||||
{
|
||||
struct v4l2_mbus_framefmt *mbusformat;
|
||||
struct mei_csi *csi = sd_to_csi(sd);
|
||||
unsigned int i;
|
||||
|
||||
mutex_lock(&csi->lock);
|
||||
|
||||
for (i = 0; i < sd->entity.num_pads; i++) {
|
||||
mbusformat = v4l2_subdev_state_get_format(sd_state, i);
|
||||
*mbusformat = mei_csi_format_mbus_default;
|
||||
}
|
||||
|
||||
mutex_unlock(&csi->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mei_csi_get_fmt(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_format *format)
|
||||
{
|
||||
struct v4l2_mbus_framefmt *mbusformat;
|
||||
struct mei_csi *csi = sd_to_csi(sd);
|
||||
|
||||
mutex_lock(&csi->lock);
|
||||
|
||||
mbusformat = mei_csi_get_pad_format(sd, sd_state, format->pad,
|
||||
format->which);
|
||||
if (mbusformat)
|
||||
format->format = *mbusformat;
|
||||
|
||||
mutex_unlock(&csi->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -388,20 +346,17 @@ static int mei_csi_set_fmt(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_format *format)
|
||||
{
|
||||
struct v4l2_mbus_framefmt *source_mbusformat;
|
||||
struct v4l2_mbus_framefmt *mbusformat;
|
||||
struct mei_csi *csi = sd_to_csi(sd);
|
||||
struct media_pad *pad;
|
||||
struct v4l2_mbus_framefmt *source_fmt;
|
||||
struct v4l2_mbus_framefmt *sink_fmt;
|
||||
|
||||
mbusformat = mei_csi_get_pad_format(sd, sd_state, format->pad,
|
||||
format->which);
|
||||
if (!mbusformat)
|
||||
return -EINVAL;
|
||||
sink_fmt = v4l2_subdev_state_get_format(sd_state, CSI_PAD_SINK);
|
||||
source_fmt = v4l2_subdev_state_get_format(sd_state, CSI_PAD_SOURCE);
|
||||
|
||||
source_mbusformat = mei_csi_get_pad_format(sd, sd_state, CSI_PAD_SOURCE,
|
||||
format->which);
|
||||
if (!source_mbusformat)
|
||||
return -EINVAL;
|
||||
if (format->pad) {
|
||||
*source_fmt = *sink_fmt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
v4l_bound_align_image(&format->format.width, 1, 65536, 0,
|
||||
&format->format.height, 1, 65536, 0, 0);
|
||||
@ -504,18 +459,8 @@ static int mei_csi_set_fmt(struct v4l2_subdev *sd,
|
||||
if (format->format.field == V4L2_FIELD_ANY)
|
||||
format->format.field = V4L2_FIELD_NONE;
|
||||
|
||||
mutex_lock(&csi->lock);
|
||||
|
||||
pad = &csi->pads[format->pad];
|
||||
if (pad->flags & MEDIA_PAD_FL_SOURCE)
|
||||
format->format = csi->format_mbus[CSI_PAD_SINK];
|
||||
|
||||
*mbusformat = format->format;
|
||||
|
||||
if (pad->flags & MEDIA_PAD_FL_SINK)
|
||||
*source_mbusformat = format->format;
|
||||
|
||||
mutex_unlock(&csi->lock);
|
||||
*sink_fmt = format->format;
|
||||
*source_fmt = *sink_fmt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -554,7 +499,7 @@ static const struct v4l2_subdev_video_ops mei_csi_video_ops = {
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_pad_ops mei_csi_pad_ops = {
|
||||
.get_fmt = mei_csi_get_fmt,
|
||||
.get_fmt = v4l2_subdev_get_fmt,
|
||||
.set_fmt = mei_csi_set_fmt,
|
||||
};
|
||||
|
||||
@ -749,6 +694,7 @@ static int mei_csi_probe(struct mei_cl_device *cldev,
|
||||
goto err_disable;
|
||||
|
||||
csi->subdev.dev = &cldev->dev;
|
||||
csi->subdev.state_lock = &csi->lock;
|
||||
v4l2_subdev_init(&csi->subdev, &mei_csi_subdev_ops);
|
||||
csi->subdev.internal_ops = &mei_csi_internal_ops;
|
||||
v4l2_set_subdevdata(&csi->subdev, csi);
|
||||
@ -764,9 +710,6 @@ static int mei_csi_probe(struct mei_cl_device *cldev,
|
||||
if (ret)
|
||||
goto err_ctrl_handler;
|
||||
|
||||
csi->format_mbus[CSI_PAD_SOURCE] = mei_csi_format_mbus_default;
|
||||
csi->format_mbus[CSI_PAD_SINK] = mei_csi_format_mbus_default;
|
||||
|
||||
csi->pads[CSI_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
|
||||
csi->pads[CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
|
||||
ret = media_entity_pads_init(&csi->subdev.entity, CSI_NUM_PADS,
|
||||
|
Loading…
Reference in New Issue
Block a user