From: Sakari Ailus <sakari.ailus@linux.intel.com>
To: Hermes.wu@ite.com.tw
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
linux-media@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 20/21] media: i2c: it6625: use centrally managed active state
Date: Fri, 18 Sep 2026 13:24:40 +0300 [thread overview]
Message-ID: <aq0RaLPX5o0HU_yC@kekkonen.localdomain> (raw)
In-Reply-To: <20260918-upstream-it6625-follow-up-patch-v1-20-78d72d7886a5@ite.com.tw>
Hi Hermes,
On Fri, Sep 18, 2026 at 04:57:35PM +0800, Hermes Wu via B4 Relay wrote:
> From: Hermes Wu <Hermes.wu@ite.com.tw>
>
> Adopt the subdev active-state model instead of a private driver mutex
> and driver-local format fields:
>
> - Share it6625_lock as both sd->state_lock and sd->ctrl_handler->lock
> (set hdl->lock right after v4l2_ctrl_handler_init(), which resets
> it, and before any control is created), matching the documented
> model in Documentation/driver-api/media/v4l2-subdev.rst. Call
> v4l2_subdev_init_finalize() after media_entity_pads_init() and
> before any code that touches active state, always before
> v4l2_async_register_subdev().
>
> - Remove csi_format/mbus_fmt_code from struct it6625 and store the
> complete format -- code, colorspace, and width/height/field derived
> from the configured DV timings -- in the pad format of each
> v4l2_subdev_state instead. it6625_set_fmt() now operates directly
> on the state the core hands it (already locked, and for ACTIVE
> already sd->active_state) instead of taking it6625_lock itself.
> it6625_get_fmt() is deleted; .get_fmt is now the core's
> v4l2_subdev_get_fmt(). it6625_init_state() seeds a state from the
> current active format when one exists (later TRY-state allocation)
> or from driver defaults when it doesn't (the very first, pre-
> assignment call that becomes the active state itself).
>
> - Keep it6625->timings as driver-private DV-timings state, but project
> its width/height/field onto the active pad format every time it
> changes (it6625_update_timings_if_changed(), it6625_clear_timings())
> so VIDIOC_SUBDEV_G_FMT stays consistent with
> VIDIOC_SUBDEV_G_DV_TIMINGS. it6625_initial_setup() and
> it6625_log_status() now read the media-bus code from the locked
> active format instead of the removed fields.
>
> - Make ACTIVE .set_fmt() transactional: return -EBUSY while streaming,
> and commit the new code/colorspace to active state only after the
> MIPI register writes that implement it actually succeed. This
> requires it6625_enable_stream_locked(), it6625_enable_stream(), and
> it6625_set_mipi_config_locked() to return int and propagate the
> first register/config-update failure; all existing callers are
> updated.
I don't think all the above is relevant in the commit message.
>
> Every it6625_lock acquisition site was re-audited against the core's
> actual locking contract (which ioctls the core state-locks, what
> v4l2_ctrl_handler_init()/_free() and v4l2_subdev_cleanup() actually
> touch) to confirm none of the driver's own lock-taking helpers are
> reachable from a path where the core already holds it6625_lock, and
> that init/teardown ordering keeps hdl->lock valid whenever
> v4l2_ctrl_handler_free() runs. The full trace is recorded in
> it6625-follow-up-patch/patch19-lock-audit.md (not part of this commit)
> for review -- it is static analysis only, since no IT6625/IT6626
> hardware is available here to exercise this with lockdep enabled.
This paragraph could go to the cover letter.
>
> Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw>
> ---
> drivers/media/i2c/it6625.c | 220 ++++++++++++++++++++++++++++-----------------
> 1 file changed, 138 insertions(+), 82 deletions(-)
>
> diff --git a/drivers/media/i2c/it6625.c b/drivers/media/i2c/it6625.c
> index ec6aaa878471ff210264a35e4aa66dfb1e63ed3b..550eb95c6f74a81fc11cc055b4590159ac50e969 100644
> --- a/drivers/media/i2c/it6625.c
> +++ b/drivers/media/i2c/it6625.c
> @@ -255,7 +255,15 @@ struct it6625 {
> struct regmap *it6625_regmap;
> enum it6625_chip_type chip_type;
>
> - /* protects concurrent access to the chip's registers and state */
> + /*
> + * Protects concurrent access to the chip's registers and state.
> + * Also shared as sd.state_lock and hdl.lock (see
This doesn't hold anymore, does it? Typically drivers do without such locks
as the subdev state lock is used instead -- assigning your own lock also
has the effect the same lock is used for try states, too.
> + * Documentation/driver-api/media/v4l2-subdev.rst), so the V4L2
> + * core already holds it across .get_fmt/.set_fmt/.enable_streams/
> + * .disable_streams and control updates -- callers reached only
> + * through those paths must use the *_locked() helpers instead of
> + * taking it again.
> + */
> struct mutex it6625_lock;
> /* serializes the complete VIDIOC_S_EDID sequence against itself */
> struct mutex edid_lock;
> @@ -291,8 +299,6 @@ struct it6625 {
> u8 csi_lanes;
> u8 port_num;
> enum v4l2_mbus_type bus_type;
> - u8 csi_format;
> - u32 mbus_fmt_code;
> /* number of EDID blocks currently loaded, protected by edid_lock */
> u8 edid_blocks;
>
> @@ -911,10 +917,11 @@ static int it6625_v4l2_sd_ctrl_update(struct v4l2_subdev *sd)
> return it6625_s_ctrl_audio_present(sd);
> }
>
> -static void it6625_enable_stream_locked(struct it6625 *it6625, bool enable)
> +static int it6625_enable_stream_locked(struct it6625 *it6625, bool enable)
> {
> struct v4l2_subdev *sd = &it6625->sd;
> int val;
> + int err;
>
> lockdep_assert_held(&it6625->it6625_lock);
>
> @@ -922,27 +929,34 @@ static void it6625_enable_stream_locked(struct it6625 *it6625, bool enable)
> __func__, enable ? "en" : "dis");
>
> val = enable ? B_MIPI_OUTPUT : 0;
> - it6625_set_bits(it6625, REG_MIPI_CONTROL, B_MIPI_OUTPUT, val);
> - it6625_update_config(it6625);
> + err = it6625_set_bits(it6625, REG_MIPI_CONTROL, B_MIPI_OUTPUT, val);
> + if (err < 0)
> + return err;
> +
> + return it6625_update_config(it6625);
> }
>
> -static void it6625_enable_stream(struct it6625 *it6625, bool enable)
> +static int it6625_enable_stream(struct it6625 *it6625, bool enable)
> {
> guard(mutex)(&it6625->it6625_lock);
> - it6625_enable_stream_locked(it6625, enable);
> + return it6625_enable_stream_locked(it6625, enable);
> }
>
> -static void it6625_set_mipi_config_locked(struct it6625 *it6625, u32 cfg_val)
> +static int it6625_set_mipi_config_locked(struct it6625 *it6625, u32 cfg_val)
> {
> u8 mipi_data_type;
> + int err;
>
> lockdep_assert_held(&it6625->it6625_lock);
>
> dev_dbg(it6625->dev, "mipi_data_type = 0x%x", cfg_val);
>
> mipi_data_type = cfg_val & 0xFF;
> - it6625_write_byte(it6625, REG_MIPI_DATA_TYPE, mipi_data_type);
> - it6625_update_config(it6625);
> + err = it6625_write_byte(it6625, REG_MIPI_DATA_TYPE, mipi_data_type);
> + if (err < 0)
> + return err;
> +
> + return it6625_update_config(it6625);
> }
>
> static inline unsigned int fps_from_bt_timings(const struct v4l2_bt_timings *t)
> @@ -957,10 +971,18 @@ static inline unsigned int fps_from_bt_timings(const struct v4l2_bt_timings *t)
>
> static void it6625_initial_setup(struct it6625 *it6625)
> {
> + struct v4l2_subdev *sd = &it6625->sd;
> + struct v4l2_mbus_framefmt *fmt;
> + int idx;
> int val = 0;
>
> guard(mutex)(&it6625->it6625_lock);
>
> + fmt = v4l2_subdev_state_get_format(v4l2_subdev_get_locked_active_state(sd), 0);
> + idx = it6625_csi_mbus_code_idx(fmt->code);
> + if (idx < 0)
> + idx = 0;
> +
> /*
> * REG_MIPI_CFG[0:2] lane count field: 1 lane -> 0, 2 lanes -> 1,
> * 3 lanes (C-PHY only) -> 3, 4 lanes (D-PHY only) -> 3.
> @@ -984,7 +1006,7 @@ static void it6625_initial_setup(struct it6625 *it6625)
> val |= FIELD_PREP(B_MIPI_SPLIT, 1);
>
> it6625_write_byte(it6625, REG_MIPI_CFG, val);
> - it6625_write_byte(it6625, REG_MIPI_DATA_TYPE, it6625->csi_format);
> + it6625_write_byte(it6625, REG_MIPI_DATA_TYPE, it6625_formats[idx].csi_format);
> it6625_write_byte(it6625, REG_MIPI_CONTROL, 0x00);
> it6625_write_byte(it6625, REG_RX_CFG, 0x00);
>
> @@ -1140,10 +1162,29 @@ static void it6625_get_timings(struct it6625 *it6625,
> *timings = it6625->timings;
> }
>
> +/*
> + * Project a DV-timings struct's width/height/field onto an active pad
> + * format. Caller must hold it6625_lock (== the active state's lock).
> + */
> +static void it6625_fill_timings_format(const struct v4l2_dv_timings *timings,
> + struct v4l2_mbus_framefmt *fmt)
> +{
> + fmt->width = timings->bt.width;
> + fmt->height = timings->bt.height;
> + fmt->field = timings->bt.interlaced == V4L2_DV_INTERLACED ?
> + V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
> +}
> +
> static void it6625_clear_timings(struct it6625 *it6625)
> {
> + struct v4l2_subdev *sd = &it6625->sd;
> + struct v4l2_mbus_framefmt *fmt;
> +
> guard(mutex)(&it6625->it6625_lock);
> memset(&it6625->timings, 0, sizeof(it6625->timings));
> +
> + fmt = v4l2_subdev_state_get_format(v4l2_subdev_get_locked_active_state(sd), 0);
> + it6625_fill_timings_format(&it6625->timings, fmt);
> }
>
> static void it6625_irq_hdmi_5v_change(struct it6625 *it6625)
> @@ -1362,7 +1403,10 @@ static int it6625_log_status(struct v4l2_subdev *sd)
>
> /* snapshot together so the reported pair was actually configured together */
> scoped_guard(mutex, &it6625->it6625_lock) {
> - mbus_fmt_code = it6625->mbus_fmt_code;
> + struct v4l2_mbus_framefmt *fmt =
> + v4l2_subdev_state_get_format(v4l2_subdev_get_locked_active_state(sd), 0);
> +
> + mbus_fmt_code = fmt->code;
> bt = it6625->timings.bt;
> }
>
> @@ -1415,6 +1459,9 @@ static int
> it6625_update_timings_if_changed(struct it6625 *it6625,
> const struct v4l2_dv_timings *timings)
> {
> + struct v4l2_subdev *sd = &it6625->sd;
> + struct v4l2_mbus_framefmt *fmt;
> +
> guard(mutex)(&it6625->it6625_lock);
>
> if (v4l2_match_dv_timings(&it6625->timings, timings, 0, false))
> @@ -1425,6 +1472,9 @@ it6625_update_timings_if_changed(struct it6625 *it6625,
>
> it6625->timings = *timings;
>
> + fmt = v4l2_subdev_state_get_format(v4l2_subdev_get_locked_active_state(sd), 0);
> + it6625_fill_timings_format(&it6625->timings, fmt);
> +
> return 1;
> }
>
> @@ -1457,8 +1507,7 @@ static int it6625_s_stream(struct v4l2_subdev *sd, int enable)
> {
> struct it6625 *it6625 = sd_to_6625(sd);
>
> - it6625_enable_stream(it6625, enable);
> - return 0;
> + return it6625_enable_stream(it6625, enable);
> }
>
> static int it6625_enum_mbus_code(struct v4l2_subdev *sd,
> @@ -1586,84 +1635,56 @@ static inline u32 format_to_colorspace(u8 csi_format)
> }
> }
>
> -static int it6625_get_fmt(struct v4l2_subdev *sd,
> - struct v4l2_subdev_state *sd_state,
> - struct v4l2_subdev_format *format)
> -{
> - struct it6625 *it6625 = sd_to_6625(sd);
> - struct v4l2_dv_timings timings;
> -
> - if (format->pad != 0)
> - return -EINVAL;
> -
> - it6625_get_timings(it6625, &timings);
> - format->format.width = timings.bt.width;
> - format->format.height = timings.bt.height;
> - format->format.field = timings.bt.interlaced == V4L2_DV_INTERLACED ?
> - V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
> -
> - if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
> - struct v4l2_mbus_framefmt *fmt;
> -
> - fmt = v4l2_subdev_state_get_format(sd_state, format->pad);
> - format->format.code = fmt->code;
> - format->format.colorspace = fmt->colorspace;
> - } else {
> - scoped_guard(mutex, &it6625->it6625_lock) {
> - format->format.colorspace =
> - format_to_colorspace(it6625->csi_format);
> - format->format.code = it6625->mbus_fmt_code;
> - }
> - }
> -
> - return 0;
> -}
> -
> static int it6625_set_fmt(struct v4l2_subdev *sd,
> struct v4l2_subdev_state *sd_state,
> struct v4l2_subdev_format *format)
> {
> struct it6625 *it6625 = sd_to_6625(sd);
> - u32 mbus_fmt_code = format->format.code;
> + struct v4l2_mbus_framefmt *fmt;
> + u32 colorspace;
> + int idx;
> int ret;
>
> - ret = it6625_get_fmt(sd, sd_state, format);
> - format->format.code = mbus_fmt_code;
> -
> - if (ret)
> - return ret;
> -
> - ret = it6625_csi_mbus_code_idx(mbus_fmt_code);
> + if (format->pad != 0)
> + return -EINVAL;
>
> - if (ret < 0) {
> + idx = it6625_csi_mbus_code_idx(format->format.code);
> + if (idx < 0) {
> v4l2_dbg(1, debug, sd,
> "%s: unsupported format code 0x%x, falling back to default",
> - __func__, mbus_fmt_code);
> - ret = 0;
> - mbus_fmt_code = it6625_formats[ret].mbus_fmt_code;
> - format->format.code = mbus_fmt_code;
> + __func__, format->format.code);
> + idx = 0;
> }
>
> - if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
> - struct v4l2_mbus_framefmt *fmt;
> + colorspace = format_to_colorspace(it6625_formats[idx].csi_format);
>
> - fmt = v4l2_subdev_state_get_format(sd_state, format->pad);
> - fmt->code = format->format.code;
> - fmt->colorspace = format_to_colorspace(it6625_formats[ret].csi_format);
> - format->format.colorspace = fmt->colorspace;
> + /* fmt already carries this state's width/height/field; leave them alone */
> + fmt = v4l2_subdev_state_get_format(sd_state, format->pad);
> +
> + if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
> + fmt->code = it6625_formats[idx].mbus_fmt_code;
> + fmt->colorspace = colorspace;
> + format->format = *fmt;
Could you rework the code to keep this for active and try paths?
> v4l2_dbg(1, debug, sd, "%s: try format code = 0x%x",
> __func__, format->format.code);
> return 0;
> }
>
> - scoped_guard(mutex, &it6625->it6625_lock) {
> - it6625->csi_format = it6625_formats[ret].csi_format;
> - it6625->mbus_fmt_code = format->format.code;
> - it6625_enable_stream_locked(it6625, false);
> - it6625_set_mipi_config_locked(it6625, it6625->csi_format);
> - }
> + if (v4l2_subdev_is_streaming(sd))
> + return -EBUSY;
>
> - format->format.colorspace = format_to_colorspace(it6625_formats[ret].csi_format);
> + ret = it6625_enable_stream_locked(it6625, false);
> + if (ret)
> + return ret;
> +
> + ret = it6625_set_mipi_config_locked(it6625, it6625_formats[idx].csi_format);
There are a few lines longer than 80; please split unless there's a
tangible reason to do otherwise.
> + if (ret)
> + return ret;
> +
> + /* commit to active state only after hardware programming succeeded */
> + fmt->code = it6625_formats[idx].mbus_fmt_code;
> + fmt->colorspace = colorspace;
> + format->format = *fmt;
>
> return 0;
> }
> @@ -1780,7 +1801,7 @@ static const struct v4l2_subdev_video_ops it6625_video_ops = {
> static const struct v4l2_subdev_pad_ops it6625_pad_ops = {
> .enum_mbus_code = it6625_enum_mbus_code,
> .set_fmt = it6625_set_fmt,
> - .get_fmt = it6625_get_fmt,
> + .get_fmt = v4l2_subdev_get_fmt,
> .get_edid = it6625_g_edid,
> .set_edid = it6625_s_edid,
> .enum_dv_timings = it6625_enum_dv_timings,
> @@ -1800,8 +1821,26 @@ static const struct v4l2_subdev_ops it6625_ops = {
> static int it6625_init_state(struct v4l2_subdev *sd,
> struct v4l2_subdev_state *sd_state)
> {
> + struct it6625 *it6625 = sd_to_6625(sd);
> + struct v4l2_subdev_state *active = v4l2_subdev_get_locked_active_state(sd);
This function should work the same way independently of whether the state
is active or not.
> struct v4l2_mbus_framefmt *fmt = v4l2_subdev_state_get_format(sd_state, 0);
>
> + /*
> + * The very first call initializes what becomes sd->active_state
> + * itself, before it's assigned -- active is NULL then, and this
> + * state gets the driver's own defaults. Every later call (opening
> + * a new file handle) initializes a fresh TRY state while the
> + * active state already exists and is locked by the same mutex
> + * (state->lock is assigned before init_state() runs), so seed it
> + * from the current active format instead of reverting to boot
> + * defaults.
> + */
> + if (active) {
> + *fmt = *v4l2_subdev_state_get_format(active, 0);
> + return 0;
> + }
> +
> + it6625_fill_timings_format(&it6625->timings, fmt);
> fmt->code = it6625_formats[0].mbus_fmt_code;
> fmt->colorspace = format_to_colorspace(it6625_formats[0].csi_format);
>
> @@ -1842,6 +1881,8 @@ static int it6625_v4l2_init_controls(struct v4l2_subdev *sd)
> it6625->csi_lanes == 3;
>
> v4l2_ctrl_handler_init(hdl, 4);
> + hdl->lock = &it6625->it6625_lock;
> +
> it6625->ctrl_5v_detect =
> v4l2_ctrl_new_std(hdl, NULL, V4L2_CID_DV_RX_POWER_PRESENT,
> 0, 1, 0, 0);
> @@ -2050,8 +2091,6 @@ static void it6625_init_data(struct it6625 *it6625)
> static struct v4l2_dv_timings default_timing =
> V4L2_DV_BT_CEA_1920X1080P60;
>
> - it6625->csi_format = it6625_formats[0].csi_format;
> - it6625->mbus_fmt_code = it6625_formats[0].mbus_fmt_code;
> it6625->timings = default_timing;
> /* firmware ships with a verified 2-block default EDID in EDID RAM */
> it6625->edid_blocks = 2;
> @@ -2246,9 +2285,16 @@ static int it6625_probe(struct i2c_client *client)
> goto err_clean_work_queues;
> }
>
> + sd->state_lock = &it6625->it6625_lock;
> + err = v4l2_subdev_init_finalize(sd);
> + if (err) {
> + dev_err(it6625->dev, "%s %d err=%d", __func__, __LINE__, err);
> + goto err_clean_hdl;
> + }
> +
> err = v4l2_ctrl_handler_setup(sd->ctrl_handler);
> if (err)
> - goto err_clean_hdl;
> + goto err_clean_state;
>
> it6625->cec_adap = cec_allocate_adapter(&it6625_cec_adap_ops,
> it6625, dev_name(it6625->dev),
> @@ -2259,7 +2305,7 @@ static int it6625_probe(struct i2c_client *client)
> if (IS_ERR(it6625->cec_adap)) {
> err = PTR_ERR(it6625->cec_adap);
> dev_err(it6625->dev, "%s %d", __func__, __LINE__);
> - goto err_clean_hdl;
> + goto err_clean_state;
> }
>
> err = cec_register_adapter(it6625->cec_adap, &client->dev);
> @@ -2267,7 +2313,7 @@ static int it6625_probe(struct i2c_client *client)
> dev_err(it6625->dev, "%s: failed to register the cec device", __func__);
> cec_delete_adapter(it6625->cec_adap);
> it6625->cec_adap = NULL;
> - goto err_clean_hdl;
> + goto err_clean_state;
> }
>
> it6625_debugfs_init(it6625, client);
> @@ -2294,6 +2340,8 @@ static int it6625_probe(struct i2c_client *client)
> v4l2_debugfs_if_free(it6625->infoframes);
> debugfs_remove_recursive(it6625->debugfs_dir);
> cec_unregister_adapter(it6625->cec_adap);
> +err_clean_state:
> + v4l2_subdev_cleanup(sd);
> err_clean_hdl:
> media_entity_cleanup(&sd->entity);
> v4l2_ctrl_handler_free(&it6625->hdl);
> @@ -2330,12 +2378,20 @@ static void it6625_remove(struct i2c_client *client)
>
> debugfs_remove_recursive(it6625->debugfs_dir);
> cec_unregister_adapter(it6625->cec_adap);
> +
> + /*
> + * v4l2_subdev_cleanup()/v4l2_ctrl_handler_free() take it6625_lock
> + * (shared as state_lock/hdl.lock), so they must run before it's
> + * destroyed.
> + */
This comment is hardly useful; the same applies to pretty much all drivers
using sub-device state and V4L2 controls.
> + v4l2_subdev_cleanup(sd);
> + media_entity_cleanup(&sd->entity);
> + v4l2_ctrl_handler_free(&it6625->hdl);
> +
> mutex_destroy(&it6625->it6625_lock);
> mutex_destroy(&it6625->edid_lock);
> mutex_destroy(&it6625->if_read_lock);
> mutex_destroy(&it6625->if_state_lock);
> - media_entity_cleanup(&sd->entity);
> - v4l2_ctrl_handler_free(&it6625->hdl);
> }
>
> static const struct i2c_device_id it6625_id[] = {
>
--
Regards,
Sakari Ailus
next prev parent reply other threads:[~2026-09-18 10:24 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-18 8:57 [PATCH 00/21] media: i2c: it6625: address review feedback and adopt subdev state Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 01/21] media: dt-bindings: ite,it6625: document the default CSI-2 bus type Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 02/21] media: i2c: it6625: propagate control-update errors Hermes Wu via B4 Relay
2026-09-18 10:05 ` Sakari Ailus
2026-09-18 11:05 ` Hermes.Wu
2026-09-18 8:57 ` [PATCH 03/21] media: i2c: it6625: default the debug module parameter to 0 Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 04/21] media: i2c: it6625: drop unused bus field from struct it6625 Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 05/21] media: i2c: it6625: drop stale GCC < 4.4.6 workaround Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 06/21] media: i2c: it6625: use unsigned int loop indices in table lookups Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 07/21] media: i2c: it6625: drop redundant parentheses in status helpers Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 08/21] media: i2c: it6625: make the audio sampling-rate table static const Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 09/21] media: i2c: it6625: tidy CEC buffer init and a continuation line Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 10/21] media: i2c: it6625: clean up it6625_wait_for_status() Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 11/21] media: i2c: it6625: use unsigned int indices in EDID read/write Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 12/21] media: i2c: it6625: use unaligned/units helpers to decode pixel clock Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 13/21] media: i2c: it6625: decode detected timings via typed register structs Hermes Wu via B4 Relay
2026-09-18 10:09 ` Sakari Ailus
2026-09-18 8:57 ` [PATCH 14/21] media: i2c: it6625: fix link-frequency reporting for one-/two-trio C-PHY Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 15/21] media: i2c: it6625: use early returns in it6625_update_timings_if_changed() Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 16/21] media: i2c: it6625: drop the private CSI-format name table Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 17/21] media: i2c: it6625: require a DT endpoint and simplify endpoint parsing Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 18/21] media: i2c: it6625: finish reverse fir-tree declaration order Hermes Wu via B4 Relay
2026-09-18 8:57 ` [PATCH 19/21] media: i2c: it6625: fold subdev initialization into probe Hermes Wu via B4 Relay
2026-09-18 10:13 ` Sakari Ailus
2026-09-18 8:57 ` [PATCH 20/21] media: i2c: it6625: use centrally managed active state Hermes Wu via B4 Relay
2026-09-18 10:24 ` Sakari Ailus [this message]
2026-09-18 11:19 ` Hermes.Wu
2026-09-18 15:28 ` Sakari Ailus
2026-09-18 8:57 ` [PATCH 21/21] media: i2c: it6625: use enable_streams and disable_streams Hermes Wu via B4 Relay
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aq0RaLPX5o0HU_yC@kekkonen.localdomain \
--to=sakari.ailus@linux.intel.com \
--cc=Hermes.wu@ite.com.tw \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=krzk+dt@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@kernel.org \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®