summaryrefslogtreecommitdiff
path: root/drivers/staging/media/imx/imx-ic-prp.c
diff options
context:
space:
mode:
authorSteve Longerbeam <slongerbeam@gmail.com>2019-08-24 13:33:37 -0300
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-10-10 07:28:25 -0300
commit2a4558c6adc455bdee6fe85db43cbc83338c0230 (patch)
tree074eb43c12d2c7b932752c7d9d1a2afe4bd63ce5 /drivers/staging/media/imx/imx-ic-prp.c
parent1f4642464655e16b70c4998a92cddc94555e2a5a (diff)
media: imx: Move pads init to probe
If a subdevice is unregistered and then registered again without the driver being removed and re-probed (which will happen when the media device is removed and re-probed without also removing/re-probing the subdevice), media_device_register_entity() is called with a non-zero entity->num_pads, and then the subdevice's .registered callback calls media_entity_pads_init(). Thus the subdevice's pad objects are added to the media device pad list twice, causing list corruption. One way to fix this would be to create media_entity_pads_destroy(), and call it in the subdevice's .unregistered callback. But calling media_entity_pads_init() in the .registered callbacks was done for legacy reasons and is no longer necessary, so move the call to media_entity_pads_init() into the subdevice's probe functions. This fixes the duplicate pad obejcts in the media device pad list. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/staging/media/imx/imx-ic-prp.c')
-rw-r--r--drivers/staging/media/imx/imx-ic-prp.c25
1 files changed, 9 insertions, 16 deletions
diff --git a/drivers/staging/media/imx/imx-ic-prp.c b/drivers/staging/media/imx/imx-ic-prp.c
index 35e60a120dc1..2a4f77e83ed3 100644
--- a/drivers/staging/media/imx/imx-ic-prp.c
+++ b/drivers/staging/media/imx/imx-ic-prp.c
@@ -428,32 +428,19 @@ static int prp_s_frame_interval(struct v4l2_subdev *sd,
return 0;
}
-/*
- * retrieve our pads parsed from the OF graph by the media device
- */
static int prp_registered(struct v4l2_subdev *sd)
{
struct prp_priv *priv = sd_to_priv(sd);
- int i, ret;
u32 code;
- for (i = 0; i < PRP_NUM_PADS; i++) {
- priv->pad[i].flags = (i == PRP_SINK_PAD) ?
- MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
- }
-
/* init default frame interval */
priv->frame_interval.numerator = 1;
priv->frame_interval.denominator = 30;
/* set a default mbus format */
imx_media_enum_ipu_format(&code, 0, CS_SEL_YUV);
- ret = imx_media_init_mbus_fmt(&priv->format_mbus, 640, 480, code,
- V4L2_FIELD_NONE, NULL);
- if (ret)
- return ret;
-
- return media_entity_pads_init(&sd->entity, PRP_NUM_PADS, priv->pad);
+ return imx_media_init_mbus_fmt(&priv->format_mbus, 640, 480, code,
+ V4L2_FIELD_NONE, NULL);
}
static const struct v4l2_subdev_pad_ops prp_pad_ops = {
@@ -487,6 +474,7 @@ static const struct v4l2_subdev_internal_ops prp_internal_ops = {
static int prp_init(struct imx_ic_priv *ic_priv)
{
struct prp_priv *priv;
+ int i;
priv = devm_kzalloc(ic_priv->ipu_dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -496,7 +484,12 @@ static int prp_init(struct imx_ic_priv *ic_priv)
ic_priv->task_priv = priv;
priv->ic_priv = ic_priv;
- return 0;
+ for (i = 0; i < PRP_NUM_PADS; i++)
+ priv->pad[i].flags = (i == PRP_SINK_PAD) ?
+ MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
+
+ return media_entity_pads_init(&ic_priv->sd.entity, PRP_NUM_PADS,
+ priv->pad);
}
static void prp_remove(struct imx_ic_priv *ic_priv)