mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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

  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®