All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "AngeloGioacchino Del Regno" <angelogioacchino.delregno@collabora.com>
Cc: dri-devel@lists.freedesktop.org, conor+dt@kernel.org,
	robh@kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH v2 02/10] drm/mediatek: Implement Display Stream Compression support
Date: Mon, 13 Jul 2026 10:13:58 +0000	[thread overview]
Message-ID: <20260713101359.ED09F1F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260713095837.16590-3-angelogioacchino.delregno@collabora.com>

Thank you for your contribution! Sashiko AI review found 16 potential issue(s) to consider:

New issues:
- [High] DSC setup overwrites the DSC control register, disabling the IP after it was started.
- [High] Uninitialized `slice_chunk_size` is used to configure hardware registers.
- [High] Integer truncation on `range_data` zeroes out the second set of RC range parameters.
- [High] Off-by-one loop boundary misses PPS 19 and the final RC range parameter.
- [High] Incorrect bitmask validation erroneously rejects valid integer BPP configurations.
- [High] State leakage of `dsc_config_done` causes bypass to be skipped when switching out of DSC modes.
- [High] Loop skips the final pipeline component, causing DSI and DSC to not be found and DSC configuration to be ignored.
- [High] Integer truncation on `dsc_pre_pad_sz` zeroes out the `DSC_PIC_PREPAD_WIDTH` configuration.
- [High] The DSI pixel stream word count assumes exactly 2 DSC slices per line, violating panel variability.
- [High] DSI link timings use uncompressed byte counts instead of compressed payloads when DSC is active.
- [High] Dangling pointer to `drm_dsc_config` leads to Use-After-Free if the DSI panel is unbound.
- [High] Unscaled RC buffer thresholds are packed into PPS registers, causing bitwise overflows.
- [Medium] Missing hardware cleanup in `mtk_dsi_poweron()` error path leaves DSI enabled but unclocked.
- [Medium] `COMPRESSED_PS_DSC` stream type is conditionally set only when the format is `MIPI_DSI_FMT_RGB888`.
- [Medium] Missing zero validation for `slice_width` and `slice_height` risks division by zero panics.

Pre-existing issues:
- [High] Caller ignores `mtk_dsi_poweron()` errors, causing unprotected writes to unclocked DSI MMIO registers.
--

--- Patch [2]: [PATCH v2 02/10] drm/mediatek: Implement Display Stream Compression support ---
commit 1aa5619e9968680600a369e5067b3b6f174817c1
Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Subject: drm/mediatek: Implement Display Stream Compression support

Add a real driver for the Display Stream Compression (DSC) Display
Controller IP, implementing support for DSC v1.1 to v1.2.

> diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
> index 8e552cdc3b53b..d4be40b2574a1 100644
> --- a/drivers/gpu/drm/mediatek/mtk_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
[ ... ]
> @@ -398,6 +401,17 @@ static int mtk_crtc_ddp_hw_init(struct mtk_crtc *mtk_crtc)
>  		if (!mtk_ddp_comp_add(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))
>  			mtk_mutex_add_comp(mtk_crtc->mutex,
>  					   mtk_crtc->ddp_comp[i]->id);
> +
> +		/* For now, only single DSI is supported */
> +		if (mtk_crtc->ddp_comp[i]->id >= DDP_COMPONENT_DSI0 &&
> +		    mtk_crtc->ddp_comp[i]->id <= DDP_COMPONENT_DSI3)
> +			if (!comp_dsi)
> +				comp_dsi = mtk_crtc->ddp_comp[i];
> +
> +		if (mtk_crtc->ddp_comp[i]->id == DDP_COMPONENT_DSC0 ||
> +		    mtk_crtc->ddp_comp[i]->id == DDP_COMPONENT_DSC1)
> +			if (!comp_dsc)
> +				comp_dsc = mtk_crtc->ddp_comp[i];
>  	}

[Severity: High]
Does this loop skip the final pipeline component? Because it iterates only to
mtk_crtc->ddp_comp_nr - 1, the final component (which is often DSI) won't be
checked, leaving comp_dsi as NULL and silently bypassing DSC configuration.

>  	if (!mtk_ddp_comp_add(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))
>  		mtk_mutex_add_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);
> @@ -413,6 +427,13 @@ static int mtk_crtc_ddp_hw_init(struct mtk_crtc *mtk_crtc)
>  		mtk_ddp_comp_start(comp);
>  	}
>  
> +	/* Setup the DSC if present, with the config coming from DSI */
> +	if (comp_dsc && comp_dsi) {
> +		dsc_cfg = mtk_dsi_get_dsc_config(comp_dsi->dev);
> +		if (dsc_cfg)
> +			mtk_ddp_comp_dsc_setup(comp_dsc, dsc_cfg);
> +	}
> +

[Severity: High]
Can calling mtk_ddp_comp_dsc_setup() after mtk_ddp_comp_start() disable the
DSC IP? Looking at mtk_dsc_setup(), it performs a direct writel() to
DISP_REG_DSC_CON which clears the DSC_EN bit that was just set during the
start phase.

>  	/* Initially configure all planes */
>  	for (i = 0; i < mtk_crtc->layer_nr; i++) {
>  		struct drm_plane *plane = &mtk_crtc->planes[i];
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_dsc.c b/drivers/gpu/drm/mediatek/mtk_disp_dsc.c
> new file mode 100644
> index 0000000000000..79b66bd7e5f3c
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_dsc.c
[ ... ]
> +static void mtk_dsc_pps_setup(struct mtk_dsc *disp_dsc, struct drm_dsc_config *dsc_cfg)
> +{
[ ... ]
> +	/* PPS 8..11 - Each register holds 4 RC buffer thresholds (PPS 11 has two) */
> +	for (i = 0; i < 4; i++) {
> +		u8 block_num = i * 4;
> +		data = 0;
> +
> +		for (j = 0; j < 4; j++) {
> +			u8 buf_index = block_num + j;
> +			u8 data_shift = j * 8;
> +
> +			/* rc_buf_thresh holds 14 elements in total */
> +			if (buf_index > 13)
> +				break;
> +
> +			data |= dsc_cfg->rc_buf_thresh[buf_index] << data_shift;

[Severity: High]
Are the RC buffer thresholds missing scaling here? The rc_buf_thresh values
can be up to 14 bits wide, but they are packed into 8-bit fields without being
right-shifted by 6, which could cause bitwise overflows into adjacent fields.

> +		}
> +		writel(data, disp_dsc->reg + DISP_REG_DSC_PPS(8 + i));
> +	}
> +
> +	/* PPS 12..19 - Each register holds two sets of RC range parameters (19 has one) */
> +	for (i = 0; i < 7; i++) {

[Severity: High]
Does this loop terminate before configuring PPS 19? The condition i < 7
means it iterates through i = 6, which covers up to PPS 18 (12 + 6). The 15th
RC range parameter in PPS 19 appears to be skipped.

> +		struct drm_dsc_rc_range_parameters *rcrp = dsc_cfg->rc_range_params;
> +		u8 block_num = i * 2;
> +		data = 0;
> +
> +		for (j = 0; j < 2; j++) {
> +			u8 buf_index = block_num + j;
> +			u8 data_shift = j * 16;
> +			u16 range_data;
> +
> +			range_data = FIELD_PREP(DSC_P12_RC_RANGE_MIN_QP,
> +						 rcrp[buf_index].range_min_qp);
> +			range_data |= FIELD_PREP(DSC_P12_RC_RANGE_MAX_QP,
> +						 rcrp[buf_index].range_max_qp);
> +			range_data |= FIELD_PREP(DSC_P12_RC_RANGE_BPG_OFFSET,
> +						 rcrp[buf_index].range_bpg_offset);
> +
> +			range_data <<= data_shift;

[Severity: High]
Could this shift cause integer truncation? The range_data variable is declared
as u16. When j=1, data_shift is 16, shifting all bits out of the u16 and
truncating it to 0, which would lose the configuration for the odd-indexed RC
range parameters.

> +			data |= range_data;
> +
> +			/* rc_range_params holds 15 elements in total */
> +			if (buf_index == 14)
> +				break;
> +		}
> +		writel(data, disp_dsc->reg + DISP_REG_DSC_PPS(12 + i));
> +	}
> +}
> +
> +void mtk_dsc_setup(struct device *dev, struct drm_dsc_config *dsc_cfg)
> +{
> +	struct mtk_dsc *disp_dsc = dev_get_drvdata(dev);
> +	u32 dsc_slice_w, dsc_slice_h, dsc_mode, dsc_cfg_rval, dsc_shadow;
> +	u32 dsc_dbg_con, dsc_con, dsc_enc_width, dsc_pic_w, dsc_pic_h;
> +	u16 pic_group_width, pic_height_ext_num, slice_group_width;
> +	u16 chunk_size, dsc_pad_num, dsc_pre_pad_sz;
[ ... ]
> +	dsc_slice_w = FIELD_PREP(DSC_SLICE_GROUP_WIDTH_M1, slice_group_width - 1);
> +	dsc_slice_w |= FIELD_PREP(DSC_SLICE_WIDTH, dsc_cfg->slice_width);
> +	dsc_slice_h = FIELD_PREP(DSC_SLICE_WIDTH_MOD3, dsc_cfg->slice_width % 3);
> +	dsc_slice_h |= FIELD_PREP(DSC_SLICE_NUM_M1,
> +				  (pic_height_ext_num / dsc_cfg->slice_height) - 1);

[Severity: Medium]
Is it possible for dsc_cfg->slice_height to be zero here, leading to a
division by zero panic? A validation check for zero slice height might be
needed.

> +	dsc_slice_h |= FIELD_PREP(DSC_SLICE_HEIGHT_M1, dsc_cfg->slice_height - 1);
> +
> +	dsc_pad_num = 3 - ((chunk_size * 2) % 3) % 3;
> +	dsc_pad_num = FIELD_PREP(DSC_PAD_NUMBER, dsc_pad_num);
> +
> +	dsc_pre_pad_sz = FIELD_PREP(DSC_PIC_PREPAD_HEIGHT, dsc_cfg->pic_height);
> +	dsc_pre_pad_sz |= FIELD_PREP(DSC_PIC_PREPAD_WIDTH, dsc_cfg->pic_width);

[Severity: High]
Will this truncate the DSC_PIC_PREPAD_WIDTH value? The variable dsc_pre_pad_sz
is declared as a u16, but DSC_PIC_PREPAD_WIDTH is defined as GENMASK(31, 16),
which means the OR operation will overflow the u16 and lose the width data.

> +
> +	dsc_mode = FIELD_PREP(DSC_INIT_DELAY_HEIGHT, 4);
[ ... ]
> +void mtk_dsc_start(struct device *dev)
> +{
> +	struct mtk_dsc *disp_dsc = dev_get_drvdata(dev);
> +
> +	/* If no DSC or config not done, set bypass mode */
> +	if (!disp_dsc->dsc_config_done) {

[Severity: High]
Does this handle transitioning from DSC to non-DSC modes correctly? Because
disp_dsc->dsc_config_done is never cleared after being set in mtk_dsc_setup(),
it looks like setting bypass mode will be skipped on subsequent starts in
non-DSC configurations.

> +		mtk_ddp_write_mask(NULL, DSC_BYPASS, &disp_dsc->cmdq_reg,
> +				   disp_dsc->reg, DISP_REG_DSC_CON, DSC_BYPASS);
> +		mtk_ddp_write_mask(NULL, DSC_UFOE_SEL, &disp_dsc->cmdq_reg,
> +				   disp_dsc->reg, DISP_REG_DSC_CON, DSC_UFOE_SEL);
> +		mtk_ddp_write_mask(NULL, DSC_DUAL_INOUT, &disp_dsc->cmdq_reg,
> +				   disp_dsc->reg, DISP_REG_DSC_CON, DSC_DUAL_INOUT);
> +	}
> +
> +	mtk_ddp_write_mask(NULL, DSC_EN, &disp_dsc->cmdq_reg,
> +			   disp_dsc->reg, DISP_REG_DSC_CON, DSC_EN);
> +}
> +
> +void mtk_dsc_stop(struct device *dev)
> +{
> +	struct mtk_dsc *disp_dsc = dev_get_drvdata(dev);
> +
> +	writel(0, disp_dsc->reg + DISP_REG_DSC_CON);
> +}
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 3f3f56eed3f92..3e22553ca990f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
[ ... ]
> @@ -395,7 +399,7 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
>  
>  static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool config_vact)
>  {
> -	u32 dsi_buf_bpp, ps_val, ps_wc, vact_nl;
> +	u32 dsi_buf_bpp, ps_val, ps_wc, size_val, vact_nl;
>  
>  	if (dsi->format == MIPI_DSI_FMT_RGB565)
>  		dsi_buf_bpp = 2;
>  	else
>  		dsi_buf_bpp = 3;
>  
>  	/* Word count */
> -	ps_wc = FIELD_PREP(DSI_PS_WC, dsi->vm.hactive * dsi_buf_bpp);
> +	if (dsi->dsc)
> +		ps_wc = FIELD_PREP(DSI_PS_WC, 2 * dsi->dsc->slice_chunk_size);

[Severity: High]
Is it safe to assume exactly 2 DSC slices per line here? If a panel requires
1, 4, or another slice count, hardcoding the multiplier to 2 could result in
improperly sized MIPI DSI packets.

> +	else
> +		ps_wc = FIELD_PREP(DSI_PS_WC, dsi->vm.hactive * dsi_buf_bpp);
>  	ps_val = ps_wc;
>  
>  	/* Pixel Stream type */
> @@ -411,7 +418,10 @@ static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool config_vact)
>  	default:
>  		fallthrough;
>  	case MIPI_DSI_FMT_RGB888:
> -		ps_val |= FIELD_PREP(DSI_PS_SEL, PACKED_PS_24BIT_RGB888);
> +		if (dsi->dsc)
> +			ps_val |= FIELD_PREP(DSI_PS_SEL, COMPRESSED_PS_DSC);
> +		else
> +			ps_val |= FIELD_PREP(DSI_PS_SEL, PACKED_PS_24BIT_RGB888);
>  		break;

[Severity: Medium]
Will this prevent compressed streams for formats other than RGB888? Since the
COMPRESSED_PS_DSC assignment is fully nested inside the MIPI_DSI_FMT_RGB888
case, using DSC with RGB666 would mistakenly signal PACKED_PS_18BIT_RGB666
over the bus.

>  	case MIPI_DSI_FMT_RGB666:
>  		ps_val |= FIELD_PREP(DSI_PS_SEL, LOOSELY_PS_24BIT_RGB666);
> @@ -565,7 +587,43 @@ static void mtk_dsi_config_vdo_timing_per_line_lp(struct mtk_dsi *dsi)
>  	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
>  }
>  
> -static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
> +static int mtk_dsi_set_dsc_params(struct mtk_dsi *dsi)
> +{
> +	struct drm_dsc_config *dsc = dsi->dsc;
> +	struct device *dev = dsi->host.dev;
> +	int ret;
> +
> +	if (dsc->bits_per_pixel & GENMASK(7, 0)) {
> +		dev_err(dev, "Fractional bits_per_pixel not supported\n");
> +		return -EINVAL;
> +	}

[Severity: High]
Could this bitmask erroneously reject valid integer bits-per-pixel values? The
bits_per_pixel value is shifted by 4 (to allow 4 fractional bits).
GENMASK(7, 0) covers the lower 8 bits, which includes 4 of the integer bits.
This would fail for a valid 8 BPP configuration.

> +
> +	if (dsc->bits_per_component != 8) {
> +		dev_err(dev, "%u bits per component is not supported\n",
> +			dsc->bits_per_component);
[ ... ]
> +static int mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
>  {
>  	struct videomode *vm = &dsi->vm;
>  
> @@ -574,17 +632,17 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
>  	writel(vm->vfront_porch, dsi->regs + DSI_VFP_NL);
>  	writel(vm->vactive, dsi->regs + DSI_VACT_NL);
>  
> -	if (dsi->driver_data->has_size_ctl)
> -		writel(FIELD_PREP(DSI_HEIGHT, vm->vactive) |
> -			FIELD_PREP(DSI_WIDTH, vm->hactive),
> -			dsi->regs + DSI_SIZE_CON);
> -
>  	if (dsi->driver_data->support_per_frame_lp)
>  		mtk_dsi_config_vdo_timing_per_frame_lp(dsi);
>  	else
>  		mtk_dsi_config_vdo_timing_per_line_lp(dsi);
>  
>  	mtk_dsi_ps_control(dsi, false);
> +
> +	if (dsi->dsc)
> +		return mtk_dsi_set_dsc_params(dsi);
> +
> +	return 0;
>  }

[Severity: High]
Is there an ordering issue here with uninitialized parameters? 
mtk_dsi_ps_control() reads dsi->dsc->slice_chunk_size, but it hasn't been
computed yet because mtk_dsi_set_dsc_params() is called afterwards.

Additionally, do the DSI timing calculations use uncompressed byte counts when
DSC is active? The functions mtk_dsi_config_vdo_timing_per_frame_lp() and
per_line_lp() calculate ps_wc using vm->hactive * dsi_tmp_buf_bpp, which
ignores the reduced compressed payload size, potentially miscomputing the
front/back porch and roundup metrics.

> @@ -741,12 +799,17 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>  
>  	mtk_dsi_ps_control(dsi, true);
>  	mtk_dsi_set_vm_cmd(dsi);
> -	mtk_dsi_config_vdo_timing(dsi);
> +	ret = mtk_dsi_config_vdo_timing(dsi);
> +	if (ret)
> +		goto err_disable_digital_clk;
> +
>  	mtk_dsi_set_interrupt_enable(dsi);
>  	mtk_dsi_lane_ready(dsi);
>  	mtk_dsi_clk_hs_mode(dsi, 1);
>  
>  	return 0;
> +err_disable_digital_clk:
> +	clk_disable_unprepare(dsi->digital_clk);
>  err_disable_engine_clk:
>  	clk_disable_unprepare(dsi->engine_clk);
>  err_phy_power_off:

[Severity: Medium]
Does this error path miss cleaning up the DSI hardware state? If
mtk_dsi_config_vdo_timing() fails, jumping to err_disable_digital_clk skips
calling mtk_dsi_disable(dsi), which was enabled earlier in mtk_dsi_poweron(),
leaving it enabled but unclocked.

[Severity: High]
This is a pre-existing issue, but does mtk_dsi_ddp_start() ignore
mtk_dsi_poweron() errors? Since mtk_dsi_poweron() can now return errors (like
when DSC parameter setup fails), mtk_dsi_ddp_start() might proceed to call
mtk_dsi_start() on unclocked hardware.

> @@ -883,6 +946,21 @@ mtk_dsi_bridge_mode_valid(struct drm_bridge *bridge,
>  	if (mode->clock * bpp / dsi->lanes > 1500000)
>  		return MODE_CLOCK_HIGH;
>  
> +	if (dsi->dsc) {
> +		if (mode->hdisplay % dsi->dsc->slice_width) {

[Severity: Medium]
Is there a risk of a division by zero panic here? If an external panel driver
supplies a zero slice_width, this modulo operation will crash.

> +			dev_err(dsi->host.dev,
> +				"DSC: hdisplay %u is not a multiple of slice width %u\n",
> +				dsi->dsc->slice_width, mode->hdisplay);
> +			return MODE_H_ILLEGAL;
> +		}
> +		if (mode->vdisplay % dsi->dsc->slice_height) {
> +			dev_err(dsi->host.dev,
> +				"DSC: vdisplay %u is not a multiple of slice height %u\n",
> +				dsi->dsc->slice_height, mode->vdisplay);
> +			return MODE_V_ILLEGAL;
> +		}
> +	}
> +
>  	return MODE_OK;
>  }
[ ... ]
> @@ -1006,6 +1091,9 @@ static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
>  			return PTR_ERR(dsi->next_bridge);
>  	}
>  
> +	if (device->dsc)
> +		dsi->dsc = device->dsc;
> +

[Severity: High]
Does this create a dangling pointer if the DSI panel is unbound? A pointer to
device->dsc is captured here, but there appears to be no corresponding code in
mtk_dsi_host_detach() to set it back to NULL, which could lead to a
use-after-free.

>  	drm_bridge_add(&dsi->bridge);
>  
>  	ret = component_add(host->dev, &mtk_dsi_component_ops);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260713095837.16590-1-angelogioacchino.delregno@collabora.com?part=2

  reply	other threads:[~2026-07-13 10:14 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-13  9:58 [PATCH v2 00/10] drm/mediatek: Add DSC, WDMA, MT8189/96 DSI support AngeloGioacchino Del Regno
2026-07-13  9:58 ` [PATCH v2 01/10] dt-bindings: display: mediatek: dsc: Add MT8196 compatible AngeloGioacchino Del Regno
2026-07-13  9:58 ` [PATCH v2 02/10] drm/mediatek: Implement Display Stream Compression support AngeloGioacchino Del Regno
2026-07-13 10:13   ` sashiko-bot [this message]
2026-07-13  9:58 ` [PATCH v2 03/10] dt-bindings: display: mediatek: dsi: Document MT8189 and MT8196 AngeloGioacchino Del Regno
2026-07-13  9:58 ` [PATCH v2 04/10] drm/mediatek: mtk_dsi: Enable interrupt at component bind time AngeloGioacchino Del Regno
2026-07-13 10:11   ` sashiko-bot
2026-07-13  9:58 ` [PATCH v2 05/10] drm/mediatek: mtk_dsi: Transfer register offsets to per-SoC const AngeloGioacchino Del Regno
2026-07-13 10:07   ` sashiko-bot
2026-07-13  9:58 ` [PATCH v2 06/10] drm/mediatek: mtk_dsi: Add support for MT8189 AngeloGioacchino Del Regno
2026-07-13 10:13   ` sashiko-bot
2026-07-13  9:58 ` [PATCH v2 07/10] drm/mediatek: mtk_dsi: Add support for MT8196 AngeloGioacchino Del Regno
2026-07-13 10:13   ` sashiko-bot
2026-07-13  9:58 ` [PATCH v2 08/10] drm/mediatek: mtk_dsi: Enable PM Runtime on probe AngeloGioacchino Del Regno
2026-07-13 10:23   ` sashiko-bot
2026-07-13  9:58 ` [PATCH v2 09/10] dt-bindings: display: mediatek: wdma: Add compatibles for more SoCs AngeloGioacchino Del Regno
2026-07-13 10:23   ` sashiko-bot
2026-07-13  9:58 ` [PATCH v2 10/10] drm/mediatek: Add Write DMA (WDMA) Engine for Writeback support AngeloGioacchino Del Regno
2026-07-13 10:26   ` sashiko-bot

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=20260713101359.ED09F1F00A3A@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.