From 1b5b3b63f0c18de9f4570a8d1843431523dcb35a Mon Sep 17 00:00:00 2001 From: Hermes Wu Date: Wed, 30 Sep 2026 14:41:37 +0800 Subject: [PATCH] media: i2c: it6625: fold subdev initialization into probe it6625_init_v4l2_subdev() split subdev/control-handler/media-entity initialization out of probe(), which made error handling harder to follow across the two functions and forced probe() to normalize every init_v4l2_subdev() failure to -ENOMEM regardless of the real error (e.g. a media_entity_pads_init() failure was reported to the caller as -ENOMEM instead of its actual code). Inline it into it6625_probe() so initialization and its unwind path are visible together, and propagate the real error from it6625_v4l2_init_controls() instead of replacing it. Cleanup behavior on each failure path is unchanged: it6625_v4l2_init_controls() already frees the control handler internally before returning an error, and a media_entity_pads_init() failure still frees it explicitly before unwinding, so neither path double-frees it through the later err_clean_hdl label. State finalization (v4l2_subdev_init_finalize()/cleanup()) is deliberately left for a follow-up change, to keep this a pure restructuring and keep the locking-model transition atomic on its own. Signed-off-by: Hermes Wu Signed-off-by: Hans Verkuil --- drivers/media/i2c/it6625.c | 46 ++++++++++++++------------------------ 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/drivers/media/i2c/it6625.c b/drivers/media/i2c/it6625.c index a270bfda9f83..5f118d7fbb59 100644 --- a/drivers/media/i2c/it6625.c +++ b/drivers/media/i2c/it6625.c @@ -2167,33 +2167,6 @@ static int it6625_parse_dt(struct it6625 *it6625) return it6625_parse_endpoint(it6625); } -static int it6625_init_v4l2_subdev(struct it6625 *it6625) -{ - struct v4l2_subdev *sd = &it6625->sd; - int err; - - sd->dev = it6625->dev; - - v4l2_i2c_subdev_init(sd, it6625->i2c_client, &it6625_ops); - sd->internal_ops = &it6625_internal_ops; - sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; - if (it6625_v4l2_init_controls(sd)) { - dev_err(it6625->dev, "Failed to initialize v4l2 controls"); - return -ENOMEM; - } - - it6625->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; - err = media_entity_pads_init(&sd->entity, 1, &it6625->pad); - if (err < 0) { - dev_err(it6625->dev, "%s %d err=%d", __func__, __LINE__, err); - v4l2_ctrl_handler_free(sd->ctrl_handler); - return err; - } - - return 0; -} - static int it6625_check_device(struct it6625 *it6625) { static const u8 chip_ids[][2] = { @@ -2279,9 +2252,23 @@ static int it6625_probe(struct i2c_client *client) } sd = &it6625->sd; - err = it6625_init_v4l2_subdev(it6625); - if (err) + v4l2_i2c_subdev_init(sd, it6625->i2c_client, &it6625_ops); + sd->internal_ops = &it6625_internal_ops; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; + + err = it6625_v4l2_init_controls(sd); + if (err) { + dev_err(it6625->dev, "failed to initialize v4l2 controls: %d", err); goto err_clean_work_queues; + } + + it6625->pad.flags = MEDIA_PAD_FL_SOURCE; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; + err = media_entity_pads_init(&sd->entity, 1, &it6625->pad); + if (err < 0) { + dev_err(it6625->dev, "%s %d err=%d", __func__, __LINE__, err); + goto err_clean_ctrl_handler; + } err = v4l2_ctrl_handler_setup(sd->ctrl_handler); if (err) @@ -2340,6 +2327,7 @@ static int it6625_probe(struct i2c_client *client) cec_unregister_adapter(it6625->cec_adap); err_clean_hdl: media_entity_cleanup(&sd->entity); +err_clean_ctrl_handler: v4l2_ctrl_handler_free(&it6625->hdl); err_clean_work_queues: