Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* RE: [EXT] Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
From: Shenwei Wang @ 2026-04-28 14:43 UTC (permalink / raw)
  To: Beleswar Prasad Padhi, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski, Andrew Lunn
In-Reply-To: <29485742-6e49-482e-b73d-228295daaeec@ti.com>



> -----Original Message-----
> From: Beleswar Prasad Padhi <b-padhi@ti.com>
> Sent: Tuesday, April 28, 2026 2:25 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>; Linus Walleij
> <linusw@kernel.org>; Bartosz Golaszewski <brgl@kernel.org>; Jonathan Corbet
> <corbet@lwn.net>; Rob Herring <robh@kernel.org>; Krzysztof Kozlowski
> <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Bjorn Andersson
> <andersson@kernel.org>; Mathieu Poirier <mathieu.poirier@linaro.org>; Frank Li
> <frank.li@nxp.com>; Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Shuah Khan <skhan@linuxfoundation.org>; linux-gpio@vger.kernel.org; linux-
> doc@vger.kernel.org; linux-kernel@vger.kernel.org; Pengutronix Kernel Team
> <kernel@pengutronix.de>; Fabio Estevam <festevam@gmail.com>; Peng Fan
> <peng.fan@nxp.com>; devicetree@vger.kernel.org; linux-
> remoteproc@vger.kernel.org; imx@lists.linux.dev; linux-arm-
> kernel@lists.infradead.org; dl-linux-imx <linux-imx@nxp.com>; Bartosz
> Golaszewski <brgl@bgdev.pl>; Andrew Lunn <andrew@lunn.ch>
> Subject: [EXT] Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> On 28/04/26 00:53, Shenwei Wang wrote:
> [...]
> 
> >
> >>> +     void *channel_devices[MAX_PORT_PER_CHANNEL];
> >>
> >> So this is technically a rpmsg endpoint (struct rpmsg_endpoint)
> >> without naming it "endpoint". Every rpmsg endpoint has a reference to
> >> its parent rpmsg channel (struct rpmsg_device) which represents the
> >> same information here. So we should use the framework standard here.
> >>
> > Yes, agree to use "endpoint_devices".
> 
> 
> I did not mean to say to just change the variable name from "channel_devices" to
> "endpoint_devices". Infact you would not need to have this field & struct
> anymore.
> 
> Pseudo-code:
> 1. Add a 'struct rpmsg_endpoint *ept' field to struct rpmsg_gpio_port
>     to maintain the ept to port idx map.
> 
> 2. Call port->ept = rpmsg_create_ept(rpdev,
>                                                             rpmsg_gpio_channel_callback,
>                                                             port, {rpdev.id.name,
>                                                             RPMSG_ADDR_ANY,
>                                                             RPMSG_ADDR_ANY})
>     from rpmsg_gpiochip_register().
> 

On the Linux side, we invoke rpmsg_create_ept. What is expected from the remote system in this case?
If the remote side does not need any extra support, this would be an excellent solution.

Thanks,
Shenwei

> 3. Send msgs from local ept in rpmsg_gpio_send_message() by:
>     rpmsg_send(port->ept, msg, sizeof(*msg));
> 
> 4. Get the port info in rpmsg_gpio_channel_callback() by:
>     struct rpmsg_gpio_port *port = priv;
> 
> Which also eliminates the need for struct rpdev_drvdata as you can just do
> rpmsg_get_rproc_node_name(rpdev) from rpmsg_gpiochip_register().
> 

^ permalink raw reply

* RE: [PATCH v2 08/11] drm/bridge: adv7511: switch to of_drm_get_bridge_by_endpoint()
From: Biju Das @ 2026-04-28 14:45 UTC (permalink / raw)
  To: Biju Das, Luca Ceresoli, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
	Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul,
	Marijn Suijten, Tian Tao, Xinwei Kong, Sumit Semwal, John Stultz,
	Andrzej Hajda, Neil Armstrong, Robert Foss, laurent.pinchart,
	Jonas Karlman, Jernej Skrabec, tomi.valkeinen, Michal Simek
  Cc: Hui Pu, Ian Ray, Thomas Petazzoni,
	dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <TY3PR01MB11346293C9AAF8BC4B3FCAD6586372@TY3PR01MB11346.jpnprd01.prod.outlook.com>

Hi Luca,

> -----Original Message-----
> From: dri-devel <dri-devel-bounces@lists.freedesktop.org> On Behalf Of Biju Das
> Sent: 28 April 2026 15:39
> Subject: RE: [PATCH v2 08/11] drm/bridge: adv7511: switch to of_drm_get_bridge_by_endpoint()
> 
> 
> 
> > -----Original Message-----
> > From: Biju Das
> > Sent: 28 April 2026 15:02
> > Subject: RE: [PATCH v2 08/11] drm/bridge: adv7511: switch to
> > of_drm_get_bridge_by_endpoint()
> >
> > Hi Luca,
> >
> > > -----Original Message-----
> > > From: Luca Ceresoli <luca.ceresoli@bootlin.com>
> > > Sent: 28 April 2026 14:48
> > > Subject: Re: [PATCH v2 08/11] drm/bridge: adv7511: switch to
> > > of_drm_get_bridge_by_endpoint()
> > >
> > > Hello,
> > >
> > > On Tue Apr 28, 2026 at 3:31 PM CEST, Biju Das wrote:
> > > >> >> > @@ -1251,10 +1251,9 @@ static int adv7511_probe(struct
> > > >> >> > i2c_client
> > > >> >> > *i2c)
> > > >> >> >
> > > >> >> >  	memset(&link_config, 0, sizeof(link_config));
> > > >> >> >
> > > >> >> > -	ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL,
> > > >> >> > -					  &adv7511->next_bridge);
> > > >> >> > -	if (ret && ret != -ENODEV)
> > > >> >> > -		return ret;
> > > >> >> > +	adv7511->bridge.next_bridge = of_drm_get_bridge_by_endpoint(dev->of_node, 1, -1);
> > > >> >> > +	if (IS_ERR(adv7511->bridge.next_bridge) && PTR_ERR(adv7511->bridge.next_bridge) != -
> ENODEV)
> > > >> >> > +		return PTR_ERR(adv7511->bridge.next_bridge);
> > > >> >>
> > > >> >> Does it crash, if the error is  -EPROBE_DEFER?
> > > >> >
> > > >> > I see a crash with patch [1], which is fixed by avoiding the direct assignment.
> > > >>
> > > >> Ah, dammit! Good catch, thanks for the quick testing and follow-up!
> > > >>
> > > >> Indeed this driver assumes next_bridge is either NULL or a valid
> > > >> pointer, but due to the 'if(IS_ERR() && some_other_condition)'
> > > >> now it can also be -ENODEV (not -
> > > EPROBE_DEFER, but that's irrelevant).
> > > >>
> > > >> This affects the msm and zynqmp_dp patches equally.
> > > >>
> > > >> I'm sending a v3 soon with these fixed. I'm just not sure which
> > > >> approach to use to fix (same for all the 3 patches). Alternatives are:
> > > >>
> > > >>  1. -ENODEV is accepted, set next_bridge to NULL when it happens:
> > > >>
> > > >>       -       if (IS_ERR(adv7511->bridge.next_bridge) && PTR_ERR(adv7511->bridge.next_bridge) !=
> -
> > > >> ENODEV)
> > > >>       -               return PTR_ERR(adv7511->bridge.next_bridge);
> > > >>       +       if (IS_ERR(adv7511->bridge.next_bridge)) {
> > > >>       +               if (PTR_ERR(adv7511->bridge.next_bridge) == -ENODEV)
> > > >>       +                       adv7511->bridge.next_bridge = NULL;
> > > >>       +               else
> > > >>       +                       return PTR_ERR(adv7511->bridge.next_bridge);
> > > >
> > > > The point is you cannot return PTR_ERR as it will lead to crash,
> > > > if it is direct assignment.
> > >
> > > It would definitely crash when the next_bridge is dereferenced
> > > (which happens in
> > > adv7511_bridge_attach()) but I don't see how it can crash here. Here
> > > it _can_ be assigned -ENODEV, but it would be immediately be cleared
> > > to NULL, or to enother error, but we'd immediately return. And in
> > > case of return, when next_bridge is cleared by __drm_bridge_free ->
> > > drm_bridge_put, the error value would
> > be ignored thanks to patch 1.
> >
> > OK, I haven't noticed the newly introduced check in drm_bridge_put() in patch#1.
> >
> > I guess, we should avoid putting error values in bridge.next_bridge.
> > It should be either NULL or Valid pointer, not PTR_ERR.
> 
> FTR, I get a crash in attach. I will apply the suggested changes and will let you know the result.
> 
> [   18.957324] pc : drm_bridge_attach+0x34/0x210 [drm]
> [   18.969425] lr : adv7511_bridge_attach+0x38/0xb8 [adv7511]
> 
> [   18.969610]  drm_bridge_attach+0x34/0x210 [drm] (P)
> [   18.969845]  adv7511_bridge_attach+0x38/0xb8 [adv7511]
> [   18.969867]  drm_bridge_attach+0xf0/0x210 [drm]
> [   18.970042]  rzg2l_mipi_dsi_attach+0x24/0x3c [rzg2l_mipi_dsi]
> [   18.970064]  drm_bridge_attach+0xf0/0x210 [drm]
> [   18.970262]  rzg2l_du_encoder_init+0x9c/0x250 [rzg2l_du_drm]
> [   18.970293]  rzg2l_du_modeset_init+0x30c/0x4d0 [rzg2l_du_drm]
> [   18.970307]  rzg2l_du_probe+0xc8/0x174 [rzg2l_du_drm]
> [   18.970321]  platform_probe+0x5c/0xa4
> [   18.970336]  really_probe+0xbc/0x2c0
> [   18.970348]  __driver_probe_device+0x80/0x14c
> [   18.970359]  driver_probe_device+0x3c/0x164
> [   18.970369]  __driver_attach+0x90/0x1a4
> [   18.970379]  bus_for_each_dev+0x7c/0xdc
> [   18.970388]  driver_attach+0x24/0x30
> [   18.970397]  bus_add_driver+0xe4/0x208
> [   18.970406]  driver_register+0x68/0x130
> [   18.970416]  __platform_driver_register+0x24/0x30
> 

I confirm the crash is fixed by your suggested changes for V3.

Cheers,
Biju

^ permalink raw reply

* Re: [PATCH 07/43] KVM: arm64: gic-v5: Create & manage VM and VPE tables
From: Vladimir Murzin @ 2026-04-28 14:54 UTC (permalink / raw)
  To: Sascha Bischoff, linux-arm-kernel@lists.infradead.org,
	kvmarm@lists.linux.dev, kvm@vger.kernel.org
  Cc: nd, maz@kernel.org, oliver.upton@linux.dev, Joey Gouly,
	Suzuki Poulose, yuzenghui@huawei.com, peter.maydell@linaro.org,
	lpieralisi@kernel.org, Timothy Hayes
In-Reply-To: <20260427160547.3129448-8-sascha.bischoff@arm.com>

Hi Sascha,

On 4/27/26 17:08, Sascha Bischoff wrote:
> +
> +	if (virt_to_phys(l2_table) & ~GICV5_VMTEL1E_L2_ADDR) {
> +		kfree(l2_table);
> +		return -EINVAL;
> +	}
> +
> +	vmt_info->l2.l2ptrs[l1_index] = l2_table;
> +
> +	/* Alignment issue! */
> +	if (virt_to_phys(l2_table) & ~GICV5_VMTEL1E_L2_ADDR) {
> +		kfree(l2_table);
> +		return -EFAULT;
> +	}
> +
> +	tmp = virt_to_phys(l2_table) & GICV5_VMTEL1E_L2_ADDR;
> +	WRITE_ONCE(vmt_info->l2.vmt_base[l1_index], cpu_to_le64(tmp));

It seems the same l2_table alignment calculated (and checked) multiple times...

Cheers
Vladimir


^ permalink raw reply

* Re: [PATCH 04/43] irqchip/gic-v5: Provide IRS config frame attrs to KVM
From: Marc Zyngier @ 2026-04-28 14:56 UTC (permalink / raw)
  To: Sascha Bischoff
  Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
	kvm@vger.kernel.org, nd, oliver.upton@linux.dev, Joey Gouly,
	Suzuki Poulose, yuzenghui@huawei.com, peter.maydell@linaro.org,
	lpieralisi@kernel.org, Timothy Hayes
In-Reply-To: <20260427160547.3129448-5-sascha.bischoff@arm.com>

On Mon, 27 Apr 2026 17:07:24 +0100,
Sascha Bischoff <Sascha.Bischoff@arm.com> wrote:
> 
> KVM needs to interact with the host IRS in order to, for example, make
> VMs or VPEs valid. There are two potential approaches here. Either the
> host irqchip driver can provide an interface, or KVM can interact
> directly with the host IRS. The latter of these two is chosen as the
> set of MMIO registers that KVM needs to interact with is orthogonal to
> the set used by the host irqchip driver (with the exception of some of
> the read-only IRS_IDRx registers).
> 
> Pass KVM a pointer to an IRS config frame - the config frame belonging
> to ANY IRS is fine as long as one IRS's config frame is used
> consistently - in struct gic_kvm_info. Additionally, include a flag
> telling KVM whether the IRS is coherent or non-coherent in order to
> make sure that KVM can do the correct cache state management, if
> required.
> 
> Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
> ---
>  drivers/irqchip/irq-gic-v5-irs.c      | 26 ++++++++++++++++++++++++++
>  drivers/irqchip/irq-gic-v5.c          |  3 +++
>  include/linux/irqchip/arm-gic-v5.h    |  2 ++
>  include/linux/irqchip/arm-vgic-info.h |  5 +++++
>  4 files changed, 36 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v5-irs.c b/drivers/irqchip/irq-gic-v5-irs.c
> index f3fce0b1e25d9..5dfa043cf9e34 100644
> --- a/drivers/irqchip/irq-gic-v5-irs.c
> +++ b/drivers/irqchip/irq-gic-v5-irs.c
> @@ -50,6 +50,32 @@ static void irs_writeq_relaxed(struct gicv5_irs_chip_data *irs_data,
>  	writeq_relaxed(val, irs_data->irs_base + reg_offset);
>  }
>  
> +void __iomem *gicv5_irs_get_config_frame_base(void)
> +{
> +	struct gicv5_irs_chip_data *irs_data = per_cpu(per_cpu_irs_data,
> +						       smp_processor_id());
> +
> +	if (!irs_data)
> +		return NULL;
> +
> +	return irs_data->irs_base;
> +}
> +
> +bool gicv5_irs_is_non_coherent(void)
> +{
> +	struct gicv5_irs_chip_data *irs_data = per_cpu(per_cpu_irs_data,
> +						       smp_processor_id());
> +
> +	if (!irs_data) {
> +		pr_err("Failed to look up IRS for CPU %d\n",
> +		       smp_processor_id());
> +		return false;
> +	}
> +
> +	return !!(irs_data->flags & IRS_FLAGS_NON_COHERENT);
> +}
> +

Frankly, we don't need these micro-helpers. Just add *one* that
returns a pointer to the IRS data for CPU0, and do the information
cherry-picking in the caller.

> +
>  /*
>   * The polling wait (in gicv5_wait_for_op_s_atomic()) on a GIC register
>   * provides the memory barriers (through MMIO accessors)
> diff --git a/drivers/irqchip/irq-gic-v5.c b/drivers/irqchip/irq-gic-v5.c
> index 58e457d4c1476..3329019722360 100644
> --- a/drivers/irqchip/irq-gic-v5.c
> +++ b/drivers/irqchip/irq-gic-v5.c
> @@ -1134,6 +1134,9 @@ static void __init gic_of_setup_kvm_info(struct device_node *node)
>  
>  	gic_v5_kvm_info.type = GIC_V5;
>  
> +	gic_v5_kvm_info.gicv5_irs.base = gicv5_irs_get_config_frame_base();
> +	gic_v5_kvm_info.gicv5_irs.non_coherent = gicv5_irs_is_non_coherent();
> +
>  	/* GIC Virtual CPU interface maintenance interrupt */
>  	gic_v5_kvm_info.no_maint_irq_mask = false;
>  	gic_v5_kvm_info.maint_irq = irq_of_parse_and_map(node, 0);

While you're at it, you may want to fix the check on the maintenance
interrupt, which gives up registering with KVM if no MI is found, even
in the absence of FEAT_GCIE_LEGACY.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply

* Re: [PATCH v4 0/3] Add i.MX94 remoteproc support and reset vector handling improvements
From: Mathieu Poirier @ 2026-04-28 15:05 UTC (permalink / raw)
  To: Peng Fan (OSS)
  Cc: Bjorn Andersson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Daniel Baluta, linux-remoteproc, devicetree, imx,
	linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260427-imx943-rproc-v4-0-68d7c7253acd@nxp.com>

On Mon, Apr 27, 2026 at 10:41:23AM +0800, Peng Fan (OSS) wrote:
> This series adds remoteproc support for the i.MX94 family, including the
> CM70, CM71, and CM33S cores, and derive the hardware reset vector for
> Cortex‑M processors whose ELF entry point does not directly correspond to
> the actual reset address.
> 
> Background:
> Cortex‑M processors fetch their initial SP and PC from a fixed reset vector
> table. While ELF images embed the entry point (e_entry), this value is
> not always aligned to the hardware reset address. On platforms such as
> i.MX94 CM33S, masking is required to compute the correct reset vector
> address before programming the SoC reset registers.
> 
> Similarly, on i.MX95, the existing implementation always programs a reset
> vector of 0x0, which only works when executing entirely from TCM. When
> firmware is loaded into DDR, the driver must pass the correct reset vector
> to the SM CPU/LMM interfaces.
> 
> Summary of patches:
> [1]dt-bindings: remoteproc: imx-rproc: Introduce fsl,reset-vector-mask
> Adds a new DT property allowing SoCs to specify a mask for deriving the
> hardware reset vector from the ELF entry point.
> 
> [2]remoteproc: imx_rproc: Program non-zero SM CPU/LMM reset vector
> Ensures the correct reset vector is passed to SM APIs by introducing a
> helper (imx_rproc_sm_get_reset_vector()) that applies the reset‑vector
> mask.
> 
> [3]remoteproc: imx_rproc: Add support for i.MX94 remoteproc
> Adds address translation tables and configuration data for CM70, CM71,
> and CM33S, enabling full remoteproc operation on i.MX94.
> 
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
> Changes in v4:
> - Daniel raised the M33S secure region was not included, but since I not
>   have image to test secure region, so drop the Secure alias region for
>   all. Updated DDR region. R-b kept since this is a minor change.
> - Add R-b for patch 2
> - Link to v3: https://lore.kernel.org/r/20260415-imx943-rproc-v3-0-9fa7528db8ca@nxp.com
>

I have applied this set.
 
> Changes in v3:
> - Patch 2: 
>   Drop R-b because of changes in V3
> 
>   Following suggestion from Mathieu that apply reset vector in
>   scmi_imx_[cpu,lmm]_reset_vector_set(), not change the meaning of
>   rproc->bootaddr, add helper imx_rproc_sm_get_reset_vector() to get reset
>   vector and use the hlper in scmi_imx_[cpu,lmm]_reset_vector_set().
> 
>   Add reset-vector-mask for i.MX95 CM7 to avoid breaking i.MX95 CM7
>   boot.
> 
> - Link to v2: https://lore.kernel.org/r/20260327-imx943-rproc-v2-0-a547a3588730@nxp.com
> 
> Changes in v2:
> - Drop fsl,reset-vector-mask by using fixed value in driver for per device
> - Add R-b for i.MX94 dt-binding
> - Update commit log to include dev addr and sys addr
> - Link to v1: https://lore.kernel.org/r/20260312-imx943-rproc-v1-0-3e66596592a8@nxp.com
> 
> ---
> Peng Fan (3):
>       dt-bindings: remoteproc: imx-rproc: Support i.MX94
>       remoteproc: imx_rproc: Program non-zero SM CPU/LMM reset vector
>       remoteproc: imx_rproc: Add support for i.MX94
> 
>  .../bindings/remoteproc/fsl,imx-rproc.yaml         |  3 +
>  drivers/remoteproc/imx_rproc.c                     | 92 +++++++++++++++++++++-
>  drivers/remoteproc/imx_rproc.h                     |  2 +
>  3 files changed, 95 insertions(+), 2 deletions(-)
> ---
> base-commit: 724699d8d0523909da51fda8d1e10c1ff867b280
> change-id: 20260311-imx943-rproc-2050e00b65f7
> 
> Best regards,
> -- 
> Peng Fan <peng.fan@nxp.com>
> 


^ permalink raw reply

* Re: [PATCH v2] arm: mediatek: MAINTAINERS: Include SoC bindings
From: Krzysztof Kozlowski @ 2026-04-28 15:07 UTC (permalink / raw)
  To: Matthias Brugger, AngeloGioacchino Del Regno, linux-kernel,
	linux-arm-kernel, linux-mediatek
In-Reply-To: <20260329085353.8649-2-krzysztof.kozlowski@oss.qualcomm.com>

On 29/03/2026 10:53, Krzysztof Kozlowski wrote:
> The ARM/ARM64 Mediatek SoC maintainer entry misses bindings directory
> for SoC devices.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
> 
> ---
> 
> FYI, there are already patches on the list which used get_maintainers.pl
> script and did not CC Mediatek maintainers, so they might get
> forgotten/missed.
> 

This patch did not receive any comments from Mediatek maintainers - do
you plan to apply it?

Best regards,
Krzysztof


^ permalink raw reply

* Re: [EXT] Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
From: Padhi, Beleswar @ 2026-04-28 15:11 UTC (permalink / raw)
  To: Shenwei Wang, Linus Walleij, Bartosz Golaszewski, Jonathan Corbet,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski, Andrew Lunn
In-Reply-To: <PAXPR04MB918568939EC7DAEB4BB6C8F989372@PAXPR04MB9185.eurprd04.prod.outlook.com>


On 4/28/2026 8:13 PM, Shenwei Wang wrote:
>
>> -----Original Message-----
>> From: Beleswar Prasad Padhi <b-padhi@ti.com>
>> Sent: Tuesday, April 28, 2026 2:25 AM
>> To: Shenwei Wang <shenwei.wang@nxp.com>; Linus Walleij
>> <linusw@kernel.org>; Bartosz Golaszewski <brgl@kernel.org>; Jonathan Corbet
>> <corbet@lwn.net>; Rob Herring <robh@kernel.org>; Krzysztof Kozlowski
>> <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Bjorn Andersson
>> <andersson@kernel.org>; Mathieu Poirier <mathieu.poirier@linaro.org>; Frank Li
>> <frank.li@nxp.com>; Sascha Hauer <s.hauer@pengutronix.de>
>> Cc: Shuah Khan <skhan@linuxfoundation.org>; linux-gpio@vger.kernel.org; linux-
>> doc@vger.kernel.org; linux-kernel@vger.kernel.org; Pengutronix Kernel Team
>> <kernel@pengutronix.de>; Fabio Estevam <festevam@gmail.com>; Peng Fan
>> <peng.fan@nxp.com>; devicetree@vger.kernel.org; linux-
>> remoteproc@vger.kernel.org; imx@lists.linux.dev; linux-arm-
>> kernel@lists.infradead.org; dl-linux-imx <linux-imx@nxp.com>; Bartosz
>> Golaszewski <brgl@bgdev.pl>; Andrew Lunn <andrew@lunn.ch>
>> Subject: [EXT] Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
>> On 28/04/26 00:53, Shenwei Wang wrote:
>> [...]
>>
>>>>> +     void *channel_devices[MAX_PORT_PER_CHANNEL];
>>>> So this is technically a rpmsg endpoint (struct rpmsg_endpoint)
>>>> without naming it "endpoint". Every rpmsg endpoint has a reference to
>>>> its parent rpmsg channel (struct rpmsg_device) which represents the
>>>> same information here. So we should use the framework standard here.
>>>>
>>> Yes, agree to use "endpoint_devices".
>>
>> I did not mean to say to just change the variable name from "channel_devices" to
>> "endpoint_devices". Infact you would not need to have this field & struct
>> anymore.
>>
>> Pseudo-code:
>> 1. Add a 'struct rpmsg_endpoint *ept' field to struct rpmsg_gpio_port
>>      to maintain the ept to port idx map.
>>
>> 2. Call port->ept = rpmsg_create_ept(rpdev,
>>                                                              rpmsg_gpio_channel_callback,
>>                                                              port, {rpdev.id.name,
>>                                                              RPMSG_ADDR_ANY,
>>                                                              RPMSG_ADDR_ANY})
>>      from rpmsg_gpiochip_register().
>>
> On the Linux side, we invoke rpmsg_create_ept. What is expected from the remote system in this case?


Nothing extra in my opinion. rpmsg_create_ept() just creates a dynamic
local endpoint address for Linux's usage. The firmware just has to make
sure to reply to the same endpoint address where it received the
message. This should already be in place IMO, because currently you are
sending all messages in the default endpoint (rpdev->ept) which is also
dynamic[1] and is created when the channel is created. And you receive
the responses correctly. (Unless you have hard-coded the default ept
address in the firmware)

[1]: 
https://github.com/torvalds/linux/blob/master/drivers/rpmsg/rpmsg_core.c#L480
(chinfo.src is RPMSG_ADDR_ANY)

Thanks,
Beleswar

> If the remote side does not need any extra support, this would be an excellent solution.
>
> Thanks,
> Shenwei
>
>> 3. Send msgs from local ept in rpmsg_gpio_send_message() by:
>>      rpmsg_send(port->ept, msg, sizeof(*msg));
>>
>> 4. Get the port info in rpmsg_gpio_channel_callback() by:
>>      struct rpmsg_gpio_port *port = priv;
>>
>> Which also eliminates the need for struct rpdev_drvdata as you can just do
>> rpmsg_get_rproc_node_name(rpdev) from rpmsg_gpiochip_register().
>>


^ permalink raw reply

* Re: [PATCH v2 08/11] drm/bridge: adv7511: switch to of_drm_get_bridge_by_endpoint()
From: Luca Ceresoli @ 2026-04-28 15:19 UTC (permalink / raw)
  To: Biju Das, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Simona Vetter, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten, Tian Tao,
	Xinwei Kong, Sumit Semwal, John Stultz, Andrzej Hajda,
	Neil Armstrong, Robert Foss, laurent.pinchart, Jonas Karlman,
	Jernej Skrabec, tomi.valkeinen, Michal Simek
  Cc: Hui Pu, Ian Ray, Thomas Petazzoni,
	dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <TY3PR01MB113466FD12513A25C0126A55F86372@TY3PR01MB11346.jpnprd01.prod.outlook.com>

Hello Biju,

On Tue Apr 28, 2026 at 4:45 PM CEST, Biju Das wrote:
> Hi Luca,
>
>> -----Original Message-----
>> From: dri-devel <dri-devel-bounces@lists.freedesktop.org> On Behalf Of Biju Das
>> Sent: 28 April 2026 15:39
>> Subject: RE: [PATCH v2 08/11] drm/bridge: adv7511: switch to of_drm_get_bridge_by_endpoint()
>>
>>
>>
>> > -----Original Message-----
>> > From: Biju Das
>> > Sent: 28 April 2026 15:02
>> > Subject: RE: [PATCH v2 08/11] drm/bridge: adv7511: switch to
>> > of_drm_get_bridge_by_endpoint()
>> >
>> > Hi Luca,
>> >
>> > > -----Original Message-----
>> > > From: Luca Ceresoli <luca.ceresoli@bootlin.com>
>> > > Sent: 28 April 2026 14:48
>> > > Subject: Re: [PATCH v2 08/11] drm/bridge: adv7511: switch to
>> > > of_drm_get_bridge_by_endpoint()
>> > >
>> > > Hello,
>> > >
>> > > On Tue Apr 28, 2026 at 3:31 PM CEST, Biju Das wrote:
>> > > >> >> > @@ -1251,10 +1251,9 @@ static int adv7511_probe(struct
>> > > >> >> > i2c_client
>> > > >> >> > *i2c)
>> > > >> >> >
>> > > >> >> >  	memset(&link_config, 0, sizeof(link_config));
>> > > >> >> >
>> > > >> >> > -	ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL,
>> > > >> >> > -					  &adv7511->next_bridge);
>> > > >> >> > -	if (ret && ret != -ENODEV)
>> > > >> >> > -		return ret;
>> > > >> >> > +	adv7511->bridge.next_bridge = of_drm_get_bridge_by_endpoint(dev->of_node, 1, -1);
>> > > >> >> > +	if (IS_ERR(adv7511->bridge.next_bridge) && PTR_ERR(adv7511->bridge.next_bridge) != -
>> ENODEV)
>> > > >> >> > +		return PTR_ERR(adv7511->bridge.next_bridge);
>> > > >> >>
>> > > >> >> Does it crash, if the error is  -EPROBE_DEFER?
>> > > >> >
>> > > >> > I see a crash with patch [1], which is fixed by avoiding the direct assignment.
>> > > >>
>> > > >> Ah, dammit! Good catch, thanks for the quick testing and follow-up!
>> > > >>
>> > > >> Indeed this driver assumes next_bridge is either NULL or a valid
>> > > >> pointer, but due to the 'if(IS_ERR() && some_other_condition)'
>> > > >> now it can also be -ENODEV (not -
>> > > EPROBE_DEFER, but that's irrelevant).
>> > > >>
>> > > >> This affects the msm and zynqmp_dp patches equally.
>> > > >>
>> > > >> I'm sending a v3 soon with these fixed. I'm just not sure which
>> > > >> approach to use to fix (same for all the 3 patches). Alternatives are:
>> > > >>
>> > > >>  1. -ENODEV is accepted, set next_bridge to NULL when it happens:
>> > > >>
>> > > >>       -       if (IS_ERR(adv7511->bridge.next_bridge) && PTR_ERR(adv7511->bridge.next_bridge) !=
>> -
>> > > >> ENODEV)
>> > > >>       -               return PTR_ERR(adv7511->bridge.next_bridge);
>> > > >>       +       if (IS_ERR(adv7511->bridge.next_bridge)) {
>> > > >>       +               if (PTR_ERR(adv7511->bridge.next_bridge) == -ENODEV)
>> > > >>       +                       adv7511->bridge.next_bridge = NULL;
>> > > >>       +               else
>> > > >>       +                       return PTR_ERR(adv7511->bridge.next_bridge);
>> > > >
>> > > > The point is you cannot return PTR_ERR as it will lead to crash,
>> > > > if it is direct assignment.
>> > >
>> > > It would definitely crash when the next_bridge is dereferenced
>> > > (which happens in
>> > > adv7511_bridge_attach()) but I don't see how it can crash here. Here
>> > > it _can_ be assigned -ENODEV, but it would be immediately be cleared
>> > > to NULL, or to enother error, but we'd immediately return. And in
>> > > case of return, when next_bridge is cleared by __drm_bridge_free ->
>> > > drm_bridge_put, the error value would
>> > be ignored thanks to patch 1.
>> >
>> > OK, I haven't noticed the newly introduced check in drm_bridge_put() in patch#1.
>> >
>> > I guess, we should avoid putting error values in bridge.next_bridge.
>> > It should be either NULL or Valid pointer, not PTR_ERR.
>>
>> FTR, I get a crash in attach. I will apply the suggested changes and will let you know the result.
>>
>> [   18.957324] pc : drm_bridge_attach+0x34/0x210 [drm]
>> [   18.969425] lr : adv7511_bridge_attach+0x38/0xb8 [adv7511]
>>
>> [   18.969610]  drm_bridge_attach+0x34/0x210 [drm] (P)
>> [   18.969845]  adv7511_bridge_attach+0x38/0xb8 [adv7511]
>> [   18.969867]  drm_bridge_attach+0xf0/0x210 [drm]
>> [   18.970042]  rzg2l_mipi_dsi_attach+0x24/0x3c [rzg2l_mipi_dsi]
>> [   18.970064]  drm_bridge_attach+0xf0/0x210 [drm]
>> [   18.970262]  rzg2l_du_encoder_init+0x9c/0x250 [rzg2l_du_drm]
>> [   18.970293]  rzg2l_du_modeset_init+0x30c/0x4d0 [rzg2l_du_drm]
>> [   18.970307]  rzg2l_du_probe+0xc8/0x174 [rzg2l_du_drm]
>> [   18.970321]  platform_probe+0x5c/0xa4
>> [   18.970336]  really_probe+0xbc/0x2c0
>> [   18.970348]  __driver_probe_device+0x80/0x14c
>> [   18.970359]  driver_probe_device+0x3c/0x164
>> [   18.970369]  __driver_attach+0x90/0x1a4
>> [   18.970379]  bus_for_each_dev+0x7c/0xdc
>> [   18.970388]  driver_attach+0x24/0x30
>> [   18.970397]  bus_add_driver+0xe4/0x208
>> [   18.970406]  driver_register+0x68/0x130
>> [   18.970416]  __platform_driver_register+0x24/0x30
>>
>
> I confirm the crash is fixed by your suggested changes for V3.

Very quick feedback loop! Thanks a lot Biju.

Sending v3 in a moment.

Luca

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply

* Re: [PATCH 05/43] KVM: arm64: gic-v5: Extract host IRS caps from IRS config frame
From: Marc Zyngier @ 2026-04-28 15:20 UTC (permalink / raw)
  To: Sascha Bischoff
  Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
	kvm@vger.kernel.org, nd, oliver.upton@linux.dev, Joey Gouly,
	Suzuki Poulose, yuzenghui@huawei.com, peter.maydell@linaro.org,
	lpieralisi@kernel.org, Timothy Hayes
In-Reply-To: <20260427160547.3129448-6-sascha.bischoff@arm.com>

On Mon, 27 Apr 2026 17:07:44 +0100,
Sascha Bischoff <Sascha.Bischoff@arm.com> wrote:
> 
> The host irqchip driver provides KVM with a pointer to an IRS's config
> frame, which allows KVM to directly interact with the host's IRS. The
> MMIO registers in the config frame are used to configure VMs (in
> addition to them being used by the host). The IRS's config frame also
> includes a set of ID registers which describe the capabilities that
> the IRS has.
> 
> Stash the pointer to the config frame, and extract the VM capabilities
> (from IRS_IDR3 & IRS_IDR4), as well as the IST
> capabilities/requirements (IRS_IDR2) from the IRS.
> 
> Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
> ---
>  arch/arm64/kvm/Makefile              |  2 +-
>  arch/arm64/kvm/vgic/vgic-v5-tables.c |  8 +++++
>  arch/arm64/kvm/vgic/vgic-v5-tables.h | 41 ++++++++++++++++++++++
>  arch/arm64/kvm/vgic/vgic-v5.c        | 52 ++++++++++++++++++++++++++++
>  include/linux/irqchip/arm-gic-v5.h   | 10 ++++++
>  5 files changed, 112 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm64/kvm/vgic/vgic-v5-tables.c
>  create mode 100644 arch/arm64/kvm/vgic/vgic-v5-tables.h
> 
> diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> index 59612d2f277c1..431de9b145ca1 100644
> --- a/arch/arm64/kvm/Makefile
> +++ b/arch/arm64/kvm/Makefile
> @@ -24,7 +24,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
>  	 vgic/vgic-mmio.o vgic/vgic-mmio-v2.o \
>  	 vgic/vgic-mmio-v3.o vgic/vgic-kvm-device.o \
>  	 vgic/vgic-its.o vgic/vgic-debug.o vgic/vgic-v3-nested.o \
> -	 vgic/vgic-v5.o
> +	 vgic/vgic-v5.o vgic/vgic-v5-tables.o
>  
>  kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
>  kvm-$(CONFIG_ARM64_PTR_AUTH)  += pauth.o
> diff --git a/arch/arm64/kvm/vgic/vgic-v5-tables.c b/arch/arm64/kvm/vgic/vgic-v5-tables.c
> new file mode 100644
> index 0000000000000..30e2b108b1aa3
> --- /dev/null
> +++ b/arch/arm64/kvm/vgic/vgic-v5-tables.c
> @@ -0,0 +1,8 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2025, 2026 Arm Ltd.
> + */
> +
> +#include "vgic-v5-tables.h"
> +
> +struct vgic_v5_host_ist_caps gicv5_host_ist_caps;
> diff --git a/arch/arm64/kvm/vgic/vgic-v5-tables.h b/arch/arm64/kvm/vgic/vgic-v5-tables.h
> new file mode 100644
> index 0000000000000..cf00a248eabd5
> --- /dev/null
> +++ b/arch/arm64/kvm/vgic/vgic-v5-tables.h
> @@ -0,0 +1,41 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2025, 2026 Arm Ltd.
> + */
> +
> +#ifndef __KVM_ARM_VGICV5_TABLES_H__
> +#define __KVM_ARM_VGICV5_TABLES_H__
> +
> +#include <linux/irqchip/arm-gic-v5.h>
> +
> +struct vgic_v5_host_ist_caps {
> +	/* IST Capabilities */
> +
> +	/* Apply to LPIs and SPIs */
> +	u8	ist_id_bits;
> +	bool	ist_levels;
> +	u8	ist_l2sz;
> +	bool	istmd;
> +	u8	istmd_sz;
> +
> +	/* LPI only */
> +	u8	min_lpi_id_bits;
> +
> +	/* VM Table, VPE Table */
> +	bool	two_level_vmt_support;
> +	u32	max_vms;
> +	u32	max_vpes;
> +	u16	vmd_size;
> +	u16	vped_size;
> +
> +	/* Is the IRS coherent with us, or not? */
> +	bool	irs_non_coherent;
> +};
> +
> +extern struct vgic_v5_host_ist_caps gicv5_host_ist_caps;
> +static inline struct vgic_v5_host_ist_caps *vgic_v5_host_caps(void)
> +{
> +	return &gicv5_host_ist_caps;
> +}

Err. No. Make gicv5_host_ist_caps static, and move the helper as
non-inline in vgic-v5-tables.c. It's not like this is anywhere near
performance-critical stuff, is it?

But also, if that's global information, we have kvm_vgic_global_state.
Isn't that where these things should live? Then the introduction of
vgic-v5-tables.[ch] can be moved to the point where it actually
matters.

> +
> +#endif
> diff --git a/arch/arm64/kvm/vgic/vgic-v5.c b/arch/arm64/kvm/vgic/vgic-v5.c
> index d4789ff3e7402..fd3d6299a2baa 100644
> --- a/arch/arm64/kvm/vgic/vgic-v5.c
> +++ b/arch/arm64/kvm/vgic/vgic-v5.c
> @@ -9,6 +9,7 @@
>  #include <linux/irqchip/arm-vgic-info.h>
>  
>  #include "vgic.h"
> +#include "vgic-v5-tables.h"
>  
>  #define ppi_caps	kvm_vgic_global_state.vgic_v5_ppi_caps
>  
> @@ -34,6 +35,54 @@ static void vgic_v5_get_implemented_ppis(void)
>  	__assign_bit(GICV5_ARCH_PPI_PMUIRQ, ppi_caps.impl_ppi_mask, system_supports_pmuv3());
>  }
>  
> +static void __iomem *irs_base;

Global state?

> +
> +static u32 irs_readl_relaxed(const u32 reg_offset)
> +{
> +	return readl_relaxed(irs_base + reg_offset);
> +}
> +
> +static int gicv5_irs_extract_vm_caps(const struct gic_kvm_info *info)
> +{
> +	u64 idr;
> +
> +	irs_base = info->gicv5_irs.base;
> +	if (!irs_base) {
> +		kvm_info("No GICv5 MMIO IRS address; no GICv5 support\n");
> +		return -ENODEV;
> +	}

Should you instead bail out early by not registering the gic_kvm_info
when the IRS base is unknown, making this sort of checks irrelevant?

Also, it's not like we can make it very far without an IRS...

> +
> +	vgic_v5_host_caps()->irs_non_coherent = info->gicv5_irs.non_coherent;
> +
> +	idr = irs_readl_relaxed(GICV5_IRS_IDR2);
> +
> +	/* We skip the LPI field as it only applies to physical LPIs */
> +	vgic_v5_host_caps()->ist_id_bits = FIELD_GET(GICV5_IRS_IDR2_ID_BITS, idr);
> +	vgic_v5_host_caps()->min_lpi_id_bits = FIELD_GET(GICV5_IRS_IDR2_MIN_LPI_ID_BITS, idr);
> +	vgic_v5_host_caps()->ist_levels = !!FIELD_GET(GICV5_IRS_IDR2_IST_LEVELS, idr);
> +	vgic_v5_host_caps()->ist_l2sz = FIELD_GET(GICV5_IRS_IDR2_IST_L2SZ, idr);
> +	vgic_v5_host_caps()->istmd = !!FIELD_GET(GICV5_IRS_IDR2_ISTMD, idr);
> +	vgic_v5_host_caps()->istmd_sz = FIELD_GET(GICV5_IRS_IDR2_ISTMD_SZ, idr);
> +
> +	idr = irs_readl_relaxed(GICV5_IRS_IDR3);
> +
> +	vgic_v5_host_caps()->max_vms = BIT(FIELD_GET(GICV5_IRS_IDR3_VM_ID_BITS, idr));
> +	vgic_v5_host_caps()->two_level_vmt_support = !!FIELD_GET(GICV5_IRS_IDR3_VMT_LEVELS, idr);
> +
> +	if (FIELD_GET(GICV5_IRS_IDR3_VMD, idr))

The constant (ab)use of FIELD_GET() for fields that are single bit
wide is very hard to read. I'd like to see:

	vgic_v5_host_caps()->ist_levels = (idr & GICV5_IRS_IDR2_IST_LEVELS);
[...]
	vgic_v5_host_caps()->istmd = (idr & GICV5_IRS_IDR2_ISTMD);
[...]
	if (idr & GICV5_IRS_IDR3_VMD)
[...]

which is infinitely more readable.

> +		vgic_v5_host_caps()->vmd_size = BIT(FIELD_GET(GICV5_IRS_IDR3_VMD_SZ, idr));
> +	else
> +		vgic_v5_host_caps()->vmd_size = 0;
> +
> +	idr = irs_readl_relaxed(GICV5_IRS_IDR4);
> +
> +	vgic_v5_host_caps()->vped_size = BIT(FIELD_GET(GICV5_IRS_IDR4_VPED_SZ, idr));
> +	/* Field stores VPE_ID_BITS - 1 */
> +	vgic_v5_host_caps()->max_vpes = BIT(FIELD_GET(GICV5_IRS_IDR4_VPE_ID_BITS, idr) + 1);
> +
> +	return 0;
> +}
> +
>  /*
>   * Probe for a vGICv5 compatible interrupt controller, returning 0 on success.
>   */
> @@ -61,6 +110,9 @@ int vgic_v5_probe(const struct gic_kvm_info *info)
>  		goto skip_v5;
>  	}
>  
> +	if (gicv5_irs_extract_vm_caps(info))
> +		goto skip_v5;
> +

We shouldn't "skip_v5" anymore. If we can't initialise KVM with GICv5,
we're done, and we should not even try to register v3.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply

* Re: [PATCH v4 3/3] coco: guest: arm64: Query host IPA-change alignment via RHI
From: Suzuki K Poulose @ 2026-04-28 15:22 UTC (permalink / raw)
  To: Marc Zyngier, Aneesh Kumar K.V
  Cc: linux-kernel, iommu, linux-coco, linux-arm-kernel, kvmarm,
	Catalin Marinas, Jason Gunthorpe, Marek Szyprowski, Robin Murphy,
	Steven Price, Thomas Gleixner, Will Deacon
In-Reply-To: <86tssvyz2v.wl-maz@kernel.org>

On 28/04/2026 14:49, Marc Zyngier wrote:
> On Tue, 28 Apr 2026 13:49:46 +0100,
> Aneesh Kumar K.V <aneesh.kumar@kernel.org> wrote:
>>
>> Marc Zyngier <maz@kernel.org> writes:
>>
>>> On Mon, 27 Apr 2026 07:31:08 +0100,
>>> "Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
>>>>
>>>> Add the Realm Host Interface support needed to query host configuration
>>>> from a Realm guest. Define the RHI hostconf SMCs, add rsi_host_call(), and
>>>> use them during Realm initialization to retrieve the host IPA-change
>>>> alignment size.
>>>
>>> I don't understand what "IPA-change" means. What you are after is the
>>> host's sharing granule size.
>>>
>>
>> This is part of the RHI specification, and the call is named
>> RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT. The intent is to determine the
>> alignment requirements for changing IPA attributes (protected vs.
>> unprotected IPA
> 
> This really is a terrible name. Why the 'change' part? It doesn't
> change, it is a constant.

Agreed, it was supposed to mean IPA_STATE_CHANGE.

> 
> Oh well...
> 
> [...]
> 

...

>>>> +unsigned long rhi_get_ipa_change_alignment(void)
>>>> +{
>>>> +	long ret;
>>>> +	unsigned long ipa_change_align;
>>>> +
>>>> +	hyp_pagesize_rhicall.imm = 0;
>>>> +	hyp_pagesize_rhicall.gprs[0] = RHI_HOSTCONF_VERSION;
>>>> +	ret = rsi_host_call(lm_alias(&hyp_pagesize_rhicall));
>>>> +	if (ret != RSI_SUCCESS)
>>>> +		goto err_out;
>>>> +
>>>> +	if (hyp_pagesize_rhicall.gprs[0] != RHI_HOSTCONF_VER_1_0)
>>>> +		goto err_out;
>>>> +
>>>> +	hyp_pagesize_rhicall.imm = 0;
>>>> +	hyp_pagesize_rhicall.gprs[0] = RHI_HOSTCONF_FEATURES;
>>>> +	ret = rsi_host_call(lm_alias(&hyp_pagesize_rhicall));
>>>> +	if (ret != RSI_SUCCESS)
>>>> +		goto err_out;
>>>> +
>>>> +	if (!(hyp_pagesize_rhicall.gprs[0] & __RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT))
>>>> +		goto err_out;
>>>> +
>>>> +	hyp_pagesize_rhicall.imm = 0;
>>>> +	hyp_pagesize_rhicall.gprs[0] = RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT;
>>>> +	ret = rsi_host_call(lm_alias(&hyp_pagesize_rhicall));
>>>> +	if (ret != RSI_SUCCESS)
>>>> +		goto err_out;
>>>> +
>>>> +	ipa_change_align = hyp_pagesize_rhicall.gprs[0];
>>>> +	/* This error needs special handling in the caller */
>>>> +	if (ipa_change_align & (SZ_4K - 1))
>>>> +		return 0;
>>>> +
>>>> +	return ipa_change_align;
>>>> +
>>>> +err_out:
>>>> +	/*
>>>> +	 * For failure condition assume host is built with 4K page size
>>>> +	 * and hence ipa change alignment can be guest PAGE_SIZE.
>>>> +	 */
>>>> +	return PAGE_SIZE;
>>>> +}
>>>
>>> Why can't this be part of rsi.c? This is an RSI call, and it should be
>>> part of the RSI initialisation.
>>>
>>
>> This is an RHI call as per the specification, hence it has been added to
>> rhi.c.
> 
> News flash: this is the Linux kernel, not an ARM spec. We organise
> things based on the logical use, not on the TLA associated with it.
> 
> And RHI is implemented in terms of RSI. In rsi.c it goes. We don't
> need this pointless proliferation of helper files that only result in
> equally pointless global symbols.

RHI (Realm Host Interface) is not really the same as RSI. The former is
a service mechanism for Realms with the "Non-secure Hypervisor".  And
this single call is just one of the services. There are further more
services that will eventually come up (e.g., Device Assignment, Boot
Sync Protocol, Firmware Activity Log etc).

RSI (to be precise, RSI_HOST_CALL) is the transport to talk to the Host,
as that is the only way for the Realm to reach the Host. So, tbh, it
does make sense to keep this in rhic ?

Suzuki


^ permalink raw reply

* [PATCH 6.6.y] arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
From: Sasha Levin @ 2026-04-28 15:24 UTC (permalink / raw)
  To: stable
  Cc: Anshuman Khandual, Will Deacon, linux-arm-kernel, linux-kernel,
	David Hildenbrand (Arm), Ryan Roberts, Catalin Marinas,
	Sasha Levin
In-Reply-To: <2026042727-accent-daylong-5b92@gregkh>

From: Anshuman Khandual <anshuman.khandual@arm.com>

[ Upstream commit 48478b9f791376b4b89018d7afdfd06865498f65 ]

During a memory hot remove operation, both linear and vmemmap mappings for
the memory range being removed, get unmapped via unmap_hotplug_range() but
mapped pages get freed only for vmemmap mapping. This is just a sequential
operation where each table entry gets cleared, followed by a leaf specific
TLB flush, and then followed by memory free operation when applicable.

This approach was simple and uniform both for vmemmap and linear mappings.
But linear mapping might contain CONT marked block memory where it becomes
necessary to first clear out all entire in the range before a TLB flush.
This is as per the architecture requirement. Hence batch all TLB flushes
during the table tear down walk and finally do it in unmap_hotplug_range().

Prior to this fix, it was hypothetically possible for a speculative access
to a higher address in the contiguous block to fill the TLB with shattered
entries for the entire contiguous range after a lower address had already
been cleared and invalidated. Due to the table entries being shattered, the
subsequent TLB invalidation for the higher address would not then clear the
TLB entries for the lower address, meaning stale TLB entries could persist.

Besides it also helps in improving the performance via TLBI range operation
along with reduced synchronization instructions. The time spent executing
unmap_hotplug_range() improved 97% measured over a 2GB memory hot removal
in KVM guest.

This scheme is not applicable during vmemmap mapping tear down where memory
needs to be freed and hence a TLB flush is required after clearing out page
table entry.

Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Closes: https://lore.kernel.org/all/aWZYXhrT6D2M-7-N@willie-the-truck/
Fixes: bbd6ec605c0f ("arm64/mm: Enable memory hot remove")
Cc: stable@vger.kernel.org
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
[ replaced `__pte_clear()` with `pte_clear()` ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/arm64/mm/mmu.c | 36 ++++++++++++++++++++----------------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index d6411f7f0b72c..8c5cbf4c858d9 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -870,10 +870,14 @@ static void unmap_hotplug_pte_range(pmd_t *pmdp, unsigned long addr,
 
 		WARN_ON(!pte_present(pte));
 		pte_clear(&init_mm, addr, ptep);
-		flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
-		if (free_mapped)
+		if (free_mapped) {
+			/* CONT blocks are not supported in the vmemmap */
+			WARN_ON(pte_cont(pte));
+			flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
 			free_hotplug_page_range(pte_page(pte),
 						PAGE_SIZE, altmap);
+		}
+		/* unmap_hotplug_range() flushes TLB for !free_mapped */
 	} while (addr += PAGE_SIZE, addr < end);
 }
 
@@ -894,15 +898,14 @@ static void unmap_hotplug_pmd_range(pud_t *pudp, unsigned long addr,
 		WARN_ON(!pmd_present(pmd));
 		if (pmd_sect(pmd)) {
 			pmd_clear(pmdp);
-
-			/*
-			 * One TLBI should be sufficient here as the PMD_SIZE
-			 * range is mapped with a single block entry.
-			 */
-			flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
-			if (free_mapped)
+			if (free_mapped) {
+				/* CONT blocks are not supported in the vmemmap */
+				WARN_ON(pmd_cont(pmd));
+				flush_tlb_kernel_range(addr, addr + PMD_SIZE);
 				free_hotplug_page_range(pmd_page(pmd),
 							PMD_SIZE, altmap);
+			}
+			/* unmap_hotplug_range() flushes TLB for !free_mapped */
 			continue;
 		}
 		WARN_ON(!pmd_table(pmd));
@@ -927,15 +930,12 @@ static void unmap_hotplug_pud_range(p4d_t *p4dp, unsigned long addr,
 		WARN_ON(!pud_present(pud));
 		if (pud_sect(pud)) {
 			pud_clear(pudp);
-
-			/*
-			 * One TLBI should be sufficient here as the PUD_SIZE
-			 * range is mapped with a single block entry.
-			 */
-			flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
-			if (free_mapped)
+			if (free_mapped) {
+				flush_tlb_kernel_range(addr, addr + PUD_SIZE);
 				free_hotplug_page_range(pud_page(pud),
 							PUD_SIZE, altmap);
+			}
+			/* unmap_hotplug_range() flushes TLB for !free_mapped */
 			continue;
 		}
 		WARN_ON(!pud_table(pud));
@@ -965,6 +965,7 @@ static void unmap_hotplug_p4d_range(pgd_t *pgdp, unsigned long addr,
 static void unmap_hotplug_range(unsigned long addr, unsigned long end,
 				bool free_mapped, struct vmem_altmap *altmap)
 {
+	unsigned long start = addr;
 	unsigned long next;
 	pgd_t *pgdp, pgd;
 
@@ -986,6 +987,9 @@ static void unmap_hotplug_range(unsigned long addr, unsigned long end,
 		WARN_ON(!pgd_present(pgd));
 		unmap_hotplug_p4d_range(pgdp, addr, next, free_mapped, altmap);
 	} while (addr = next, addr < end);
+
+	if (!free_mapped)
+		flush_tlb_kernel_range(start, end);
 }
 
 static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
-- 
2.53.0



^ permalink raw reply related

* Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
From: Shenwei Wang @ 2026-04-28 15:24 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Padhi, Beleswar, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski
In-Reply-To: <6e01e114-e336-4744-b6b4-563ec42e321b@lunn.ch>



> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Monday, April 27, 2026 3:49 PM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Padhi, Beleswar <b-padhi@ti.com>; Linus Walleij <linusw@kernel.org>;
> Bartosz Golaszewski <brgl@kernel.org>; Jonathan Corbet <corbet@lwn.net>;
> Rob Herring <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>;
> Conor Dooley <conor+dt@kernel.org>; Bjorn Andersson
> <andersson@kernel.org>; Mathieu Poirier <mathieu.poirier@linaro.org>; Frank Li
> <frank.li@nxp.com>; Sascha Hauer <s.hauer@pengutronix.de>; Shuah Khan
> <skhan@linuxfoundation.org>; linux-gpio@vger.kernel.org; linux-
> doc@vger.kernel.org; linux-kernel@vger.kernel.org; Pengutronix Kernel Team
> <kernel@pengutronix.de>; Fabio Estevam <festevam@gmail.com>; Peng Fan
> <peng.fan@nxp.com>; devicetree@vger.kernel.org; linux-
> remoteproc@vger.kernel.org; imx@lists.linux.dev; linux-arm-
> kernel@lists.infradead.org; dl-linux-imx <linux-imx@nxp.com>; Bartosz
> Golaszewski <brgl@bgdev.pl>
> Subject: [EXT] Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > > struct virtio_gpio_response {
> > >         __u8 status;
> > >         __u8 value;
> > > };
> 
> > It is the same message format. Please see the message definition
> (GET_DIRECTION) below:
> 
> > +   +-----+-----+-----+-----+-----+----+
> > +   |0x00 |0x01 |0x02 |0x03 |0x04 |0x05|
> > +   | 1   | 2   |port |line | err | dir|
> > +   +-----+-----+-----+-----+-----+----+
> 
> Sorry, but i don't see how two u8 vs six u8 are the same message format.
> 

Some changes to the message format are necessary.

Virtio uses two communication channels (virtqueues): one for requests and replies, and a second one for events. 
In contrast, rpmsg provides only a single communication channel, so a type field is required to distinguish between 
different kinds of messages.

Since rpmsg replies and events share the same message format, an additional line is introduced to handle both cases.

Finally, rpmsg supports multiple GPIO controllers, so a port field is added to uniquely identify the target controller.

Shenwei

>        Andrew


^ permalink raw reply

* Re: [PATCH] iommu/rockchip: disable fetch dte time limit
From: Heiko Stuebner @ 2026-04-28 15:29 UTC (permalink / raw)
  To: Shawn Lin, Joerg Roedel, Will Deacon, Robin Murphy,
	Sven Püschel
  Cc: iommu, linux-arm-kernel, linux-rockchip, linux-kernel, Simon Xue,
	kernel
In-Reply-To: <ece1961d-d16c-40c8-8f42-55bd0f0eda27@pengutronix.de>

Hi Sven,

Am Dienstag, 28. April 2026, 14:15:45 Mitteleuropäische Sommerzeit schrieb Sven Püschel:
> Hi,
> 
> pinging this Patch, as I didn't receive any more feedback/reviews. The 
> feedback only affects the comment and doesn't affect the commit, 
> therefore I currently don't see a reason for a v2.

it's been 5 months since the original submission, so I'd disagree :-)
It may very well have already been discarded from maintainers' inboxes.

So I do think a v2 or at least a resend is waranted here.


Heiko


> We've noticed that this patches fixes hangups when using the RGA3 
> peripheral on the rk3588 (where I'm in the process of upstreaming a 
> driver [1], which depends on this changeset). Based on the vendor commit 
> messages, it should also fix VOP and screen black issues.
> 
> Sincerely
>      Sven
> 
> [1] 
> https://lore.kernel.org/linux-media/20260428-spu-rga3-v5-0-eb7f5d019d86@pengutronix.de/
> 
> On 11/28/25 8:26 AM, Sven Püschel wrote:
> >
> > On 11/27/25 5:32 AM, Shawn Lin wrote:
> >> 在 2025/11/26 星期三 19:45, Sven Püschel 写道:
> >>> From: Simon Xue <xxm@rock-chips.com>
> >>>
> >>> Disable the Bit 31 of the AUTO_GATING iommu register, as it causes
> >>> hangups with the RGA3 (Raster Graphics Acceleration 3) peripheral.
> >>> The RGA3 register description of the TRM already states that the bit
> >>> must be set to 1. The vendor kernel sets the bit unconditionally to
> >>> 1 to fix VOP (Video Output Processor) screen black issues. This patch
> >>> squashes the 2 vendor kernel commits with the following commit 
> >>> messages:
> >>>
> >>> Master fetch data and cpu update page table may work in parallel, may
> >>> have the following procedure:
> >>>
> >>>     master                  cpu
> >>>     fetch dte               update page tabl
> >>>             |                       |
> >>>     (make dte invalid)  <-  zap iotlb entry
> >>>             |                       |
> >>>     fetch dte again
> >>>     (make dte invalid)  <-  zap iotlb entry
> >>>             |                       |
> >>>     fetch dte again
> >>>     (make dte invalid)  <-  zap iotlb entry
> >>>             |                       |
> >>>     fetch dte again
> >>>     (make iommu block)  <-  zap iotlb entry
> >>>
> >>> New iommu version has the above bug, if fetch dte consecutively four
> >>> times, then it will be blocked. Fortunately, we can set bit 31 of
> >>> register MMU_AUTO_GATING to 1 to make it work as old version which does
> >>> not have this issue.
> >>>
> >>> This issue only appears on RV1126 so far, so make a workaround 
> >>> dedicated
> >>> to "rockchip,rv1126" machine type.
> >>>
> >>> iommu/rockchip: fix vop blocked and screen black on RK356X and RK3588
> >>>
> >>> RK3568 and RK3588 has the same issue as RV1126/RV1109 that caused by
> >>> dte fetch time limit, So we can set BIT(31) of register 0x24 default
> >>> to 1 as a workaround.
> >>>
> >>> Signed-off-by: Simon Xue <xxm@rock-chips.com>
> >>> Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
> >>> ---
> >>> During testing of a newly developed driver for the RGA3 peripheral [1]
> >>> (Raster Graphic Acceleration 3) of the RK3588 some sporadic hangs
> >>> have been observed. The upstream rockchip-iommu driver is used to 
> >>> handle
> >>> the RGA3 IOMMU register space.
> >>>
> >>> After a closer look at the TRM for the RK3588, the RGA3 iommu register
> >>> description of the RGA3_MMU_AUTO_GATING register (offset 0x24) mentions
> >>
> >> It's 0xF24 per RGA3 chapter.
> >
> > yeah, sorry. I was already thinking relative to the rga3 iommu address 
> > space in my head, but didn't really mention that the chapter says 
> > 0xF24 with the iommu related registers starting at 0xF00.
> >
> > Sincerely
> >     Sven
> >
> >>
> >>> a mmu_bug_fixed_disable bit, which must be set to 1 but defaults to 0.
> >>>
> >>> Looking at the commits in the vendor kernel, the bit is unconditionally
> >>> set to 1 and mentions that it fixes a blocked VOP (Video Output
> >>> Processor) [3]. Therefore squash the relevant vendor commits
> >>> [2] and [3] into a single patch, combine the commit messages and keep
> >>> the Signed-off-by line from the original author.
> >>>
> >>> [1] 
> >>> https://lore.kernel.org/all/20251007-spu-rga3-v1-0-36ad85570402@pengutronix.de/
> >>> [2] 
> >>> https://github.com/rockchip-linux/kernel/commit/7f8158fb41b5cc8e738aaeebc3637c50ebd74cae
> >>> [3] 
> >>> https://github.com/rockchip-linux/kernel/commit/6a355e5f9a2069a2309e240791bc3aad63b7324e
> >>> ---
> >>>   drivers/iommu/rockchip-iommu.c | 8 ++++++++
> >>>   1 file changed, 8 insertions(+)
> >>>
> >>> diff --git a/drivers/iommu/rockchip-iommu.c 
> >>> b/drivers/iommu/rockchip-iommu.c
> >>> index 0861dd469bd86..2d0dabb0d101a 100644
> >>> --- a/drivers/iommu/rockchip-iommu.c
> >>> +++ b/drivers/iommu/rockchip-iommu.c
> >>> @@ -76,6 +76,8 @@
> >>>   #define SPAGE_ORDER 12
> >>>   #define SPAGE_SIZE (1 << SPAGE_ORDER)
> >>>   +#define DISABLE_FETCH_DTE_TIME_LIMIT BIT(31)
> >>> +
> >>>    /*
> >>>     * Support mapping any size that fits in one page table:
> >>>     *   4 KiB to 4 MiB
> >>> @@ -930,6 +932,7 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
> >>>       struct iommu_domain *domain = iommu->domain;
> >>>       struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
> >>>       int ret, i;
> >>> +    u32 auto_gate;
> >>>         ret = clk_bulk_enable(iommu->num_clocks, iommu->clocks);
> >>>       if (ret)
> >>> @@ -948,6 +951,11 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
> >>> rk_ops->mk_dtentries(rk_domain->dt_dma));
> >>>           rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
> >>>           rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, 
> >>> RK_MMU_IRQ_MASK);
> >>> +
> >>> +        /* Workaround for iommu blocked, BIT(31) default to 1 */
> >>> +        auto_gate = rk_iommu_read(iommu->bases[i], 
> >>> RK_MMU_AUTO_GATING);
> >>> +        auto_gate |= DISABLE_FETCH_DTE_TIME_LIMIT;
> >>> +        rk_iommu_write(iommu->bases[i], RK_MMU_AUTO_GATING, 
> >>> auto_gate);
> >>>       }
> >>>         ret = rk_iommu_enable_paging(iommu);
> >>>
> >>> ---
> >>> base-commit: 30f09200cc4aefbd8385b01e41bde2e4565a6f0e
> >>> change-id: 20251126-spu-iommudtefix-cd0c5244c74a
> >>>
> >>> Best regards,
> >>
> >>
> 






^ permalink raw reply

* [PATCH v3 00/11] drm/bridge: handle refcounting for bridge-only callers of drm_of_find_panel_or_bridge()
From: Luca Ceresoli @ 2026-04-28 15:30 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
	Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul,
	Marijn Suijten, Xinliang Liu, Sumit Semwal, Yongqin Liu,
	John Stultz, Tomi Valkeinen, Michal Simek
  Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, linux-arm-kernel, Luca Ceresoli,
	Laurent Pinchart, Dmitry Baryshkov

This series converts all the bridge-only callers of the deprecated
drm_of_find_panel_or_bridge() API to a new, simpler API that handles bridge
refcounting.

== Series description

 * Patch 1 (new in v2) makes drm_bridge_get/put() ignore ERR_PTR pointers,
   not only NULL pointers
 * Patch 2 introduces of_drm_get_bridge_by_endpoint() as a replacement for
   bridge-only calls to drm_of_find_panel_or_bridge(); the new function
   refcounts the bridge and is simpler
 * The following patches convert all bridge-only users to the new API
 * The last patch forbids new bridge-only calls to
   drm_of_find_panel_or_bridge()

== Grand plan

This is part of the work to support hotplug of DRM bridges. The grand plan
was discussed in [0].

Here's the work breakdown (➜ marks the current series):

 1. ➜ add refcounting to DRM bridges struct drm_bridge,
      based on devm_drm_bridge_alloc()
    A. ✔ add new alloc API and refcounting (v6.16)
    B. ✔ convert all bridge drivers to new API (v6.17)
    C. ✔ kunit tests (v6.17)
    D. ✔ add get/put to drm_bridge_add/remove() + attach/detach()
         and warn on old allocation pattern (v6.17)
    E. ➜ add get/put on drm_bridge accessors
       1. ✔ drm_bridge_chain_get_first_bridge(), add cleanup action (v6.18)
       2. ✔ drm_bridge_get_prev_bridge() (v6.18)
       3. ✔ drm_bridge_get_next_bridge() (v6.19)
       4. ✔ drm_for_each_bridge_in_chain() (v6.19)
       5. ✔ drm_bridge_connector_init (v6.19)
       6. ✔ protect encoder bridge chain with a mutex (v7.2)
       7. ➜ of_drm_find_bridge
          a. ✔ add of_drm_get_bridge() (v7.0),
               convert basic direct users (v7.0-v7.1)
          b. ✔ convert direct of_drm_get_bridge() users, part 2 (v7.0)
          c. ✔ convert direct of_drm_get_bridge() users, part 3 (v7.0)
          d. ✔ convert direct of_drm_get_bridge() users, part 4 (v7.1-v7.2)
          e. ➜ convert bridge-only drm_of_find_panel_or_bridge() users
       8. drm_of_find_panel_or_bridge, *_of_get_bridge
       9. ✔ enforce drm_bridge_add before drm_bridge_attach (v6.19)
    F. ✔ debugfs improvements
       1. ✔ add top-level 'bridges' file (v6.16)
       2. ✔ show refcount and list lingering bridges (v6.19)
 2. … handle gracefully atomic updates during bridge removal
    A. ✔ Add drm_bridge_enter/exit() to protect device resources (v7.0)
    B. … protect private_obj removal from list
    C. ✔ Add drm_bridge_clear_and_put() (v7.1)
 3. … DSI host-device driver interaction
 4. ✔ removing the need for the "always-disconnected" connector
 5. ✔ Migrate i.MX LCDIF driver to bridge-connector (v7.2)
 6. … DRM bridge hotplug
    A. … Bridge hotplug management in the DRM core
       1. … bridge-connector: attach encoder to the connector
    B.   Device tree description

[0] https://lore.kernel.org/lkml/20250206-hotplug-drm-bridge-v6-0-9d6f2c9c3058@bootlin.com/#t

Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
Changes in v3:
- patch 3, 8, 10: fixed ERR_PTR deref in the -ENODEV case, and removed
  Dmitry's R-by from those patches as they are changed
- Added review trailers to the other patches
- Link to v2: https://patch.msgid.link/20260428-drm-bridge-alloc-getput-panel_or_bridge-v2-0-4300744a1c47@bootlin.com

Changes in v2:
- Added patch to ignore ERR_PTR values in drm_bridge_get/put()
- Changed API to return the bridge (or a ERR_PTR) in the return value,
  not as a double-pointer output parameter
- Adapted all patches to the new API, dropped Dmitry's review tags as the
  patches are all modified
- Removed bouncing addresses from Cc list
- Link to v1: https://patch.msgid.link/20260413-drm-bridge-alloc-getput-panel_or_bridge-v1-0-acd01cd79a1f@bootlin.com

---
Luca Ceresoli (11):
      drm/bridge: drm_bridge_get/put(): ignore ERR_PTR
      drm/bridge: add of_drm_get_bridge_by_endpoint()
      drm/msm/hdmi: switch to of_drm_get_bridge_by_endpoint()
      drm/hisilicon/kirin: switch to of_drm_get_bridge_by_endpoint()
      drm/bridge: chrontel-ch7033: switch to of_drm_get_bridge_by_endpoint()
      drm/bridge: lontium-lt9611uxc: switch to of_drm_get_bridge_by_endpoint()
      drm/bridge: lt9611: switch to of_drm_get_bridge_by_endpoint()
      drm/bridge: adv7511: switch to of_drm_get_bridge_by_endpoint()
      drm/bridge: lt8713sx: switch to of_drm_get_bridge_by_endpoint()
      drm: zynqmp_dp: switch to of_drm_get_bridge_by_endpoint()
      drm: of: forbid bridge-only calls to drm_of_find_panel_or_bridge()

 drivers/gpu/drm/bridge/adv7511/adv7511.h     |  1 -
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 15 ++++----
 drivers/gpu/drm/bridge/chrontel-ch7033.c     | 28 +++++++--------
 drivers/gpu/drm/bridge/lontium-lt8713sx.c    | 10 +++---
 drivers/gpu/drm/bridge/lontium-lt9611.c      |  9 +++--
 drivers/gpu/drm/bridge/lontium-lt9611uxc.c   |  9 +++--
 drivers/gpu/drm/drm_bridge.c                 | 53 ++++++++++++++++++++++++----
 drivers/gpu/drm/drm_of.c                     | 26 +++++++-------
 drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c |  9 +++--
 drivers/gpu/drm/msm/hdmi/hdmi.c              | 11 ++++--
 drivers/gpu/drm/xlnx/zynqmp_dp.c             | 19 +++++-----
 include/drm/drm_bridge.h                     |  8 +++++
 12 files changed, 128 insertions(+), 70 deletions(-)
---
base-commit: 6dbe0c5375e4f88c8d7c90790e0ea29d565b5d0a
change-id: 20260410-drm-bridge-alloc-getput-panel_or_bridge-42501b38eaad

Best regards,
--  
Luca Ceresoli <luca.ceresoli@bootlin.com>



^ permalink raw reply

* [PATCH v3 01/11] drm/bridge: drm_bridge_get/put(): ignore ERR_PTR
From: Luca Ceresoli @ 2026-04-28 15:30 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
	Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul,
	Marijn Suijten, Xinliang Liu, Sumit Semwal, Yongqin Liu,
	John Stultz, Tomi Valkeinen, Michal Simek
  Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, linux-arm-kernel, Luca Ceresoli,
	Laurent Pinchart, Dmitry Baryshkov
In-Reply-To: <20260428-drm-bridge-alloc-getput-panel_or_bridge-v3-0-a537b5567add@bootlin.com>

Most functions returning a struct drm_bridge pointer currently return a
valid pointer or NULL, but this restricts their ability to return an error
code describing the error kind.

In preparation to have new APIs that can return a struct drm_bridge pointer
holding an ERR_PTR (and for those which already do) make drm_bridge_get()
and drm_bridge_put() ignore ERR_PTR values, just like they ignore NULL
pointers.

This will avoid annoying error checking in many places and the risk of
missing error checks.

Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://lore.kernel.org/all/20260318152533.GA633439@killaraus.ideasonboard.com/
Suggested-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://lore.kernel.org/all/omlnswxukeqgnatzdvooaashgkfcacjevkvbkm6xt33itgua2k@jcmzll2w6kdq/
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
Patch added in v2
---
 drivers/gpu/drm/drm_bridge.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 986e4c79a4e0..cea5babbe99e 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -282,7 +282,7 @@ static void __drm_bridge_free(struct kref *kref)
 
 /**
  * drm_bridge_get - Acquire a bridge reference
- * @bridge: DRM bridge; if NULL this function does nothing
+ * @bridge: DRM bridge; if NULL or an ERR_PTR this function does nothing
  *
  * This function increments the bridge's refcount.
  *
@@ -291,7 +291,7 @@ static void __drm_bridge_free(struct kref *kref)
  */
 struct drm_bridge *drm_bridge_get(struct drm_bridge *bridge)
 {
-	if (bridge)
+	if (!IS_ERR_OR_NULL(bridge))
 		kref_get(&bridge->refcount);
 
 	return bridge;
@@ -300,7 +300,7 @@ EXPORT_SYMBOL(drm_bridge_get);
 
 /**
  * drm_bridge_put - Release a bridge reference
- * @bridge: DRM bridge; if NULL this function does nothing
+ * @bridge: DRM bridge; if NULL or an ERR_PTR this function does nothing
  *
  * This function decrements the bridge's reference count and frees the
  * object if the reference count drops to zero.
@@ -310,7 +310,7 @@ EXPORT_SYMBOL(drm_bridge_get);
  */
 void drm_bridge_put(struct drm_bridge *bridge)
 {
-	if (bridge)
+	if (!IS_ERR_OR_NULL(bridge))
 		kref_put(&bridge->refcount, __drm_bridge_free);
 }
 EXPORT_SYMBOL(drm_bridge_put);
@@ -319,8 +319,8 @@ EXPORT_SYMBOL(drm_bridge_put);
  * drm_bridge_clear_and_put - Given a bridge pointer, clear the pointer
  *                            then put the bridge
  * @bridge_pp: pointer to pointer to a struct drm_bridge; ``bridge_pp``
- *             must be non-NULL; if ``*bridge_pp`` is NULL this function
- *             does nothing
+ *             must be non-NULL; if ``*bridge_pp`` is NULL or an ERR_PTR
+ *             this function does nothing
  *
  * Helper to put a DRM bridge, but only after setting its pointer to
  * NULL. Useful when a struct drm_bridge reference must be dropped without

-- 
2.53.0



^ permalink raw reply related

* [PATCH v3 02/11] drm/bridge: add of_drm_get_bridge_by_endpoint()
From: Luca Ceresoli @ 2026-04-28 15:30 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
	Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul,
	Marijn Suijten, Xinliang Liu, Sumit Semwal, Yongqin Liu,
	John Stultz, Tomi Valkeinen, Michal Simek
  Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, linux-arm-kernel, Luca Ceresoli,
	Dmitry Baryshkov
In-Reply-To: <20260428-drm-bridge-alloc-getput-panel_or_bridge-v3-0-a537b5567add@bootlin.com>

drm_of_find_panel_or_bridge() is widely used, but many callers pass NULL
into the @panel or the @bridge arguments, thus making a very partial usage
of this rather complex function.

Besides, the bridge returned in @bridge is not refcounted, thus making this
API unsafe when DRM bridge hotplug will be introduced.

Solve both issues for the cases of calls to drm_of_find_panel_or_bridge()
with a NULL @panel pointer by adding a new function that only looks for
bridges (and is thus much simpler) and increments the refcount of the
returned bridge.

The new function is identical to drm_of_find_panel_or_bridge() except it:

 - handles bridge refcounting: uses of_drm_find_and_get_bridge() instead of
   of_drm_find_bridge() internally to return a refcounted bridge
 - is simpler to use: just takes no @panel parameter, returns the pointer
   in the return value instead of a double pointer argument
 - has a simpler implementation: it is equal to
   drm_of_find_panel_or_bridge() after removing the code that becomes dead
   when @panel == NULL

Also add this function to drm_bridge.c and not drm_of.c because it returns
bridges only.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
Changes in v2:
- return the bridge in the return value, not a double pointer
---
 drivers/gpu/drm/drm_bridge.c | 41 +++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_bridge.h     |  8 ++++++++
 2 files changed, 49 insertions(+)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index cea5babbe99e..8a4141bb7b31 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -1582,6 +1582,47 @@ struct drm_bridge *of_drm_find_bridge(struct device_node *np)
 	return bridge;
 }
 EXPORT_SYMBOL(of_drm_find_bridge);
+
+/**
+ * of_drm_get_bridge_by_endpoint - return DRM bridge connected to a port/endpoint
+ * @np: device tree node containing output ports
+ * @port: port in the device tree node, or -1 for the first port found
+ * @endpoint: endpoint in the device tree node, or -1 for the first endpoint found
+ *
+ * Given a DT node's port and endpoint number, find the connected node and
+ * return the associated drm_bridge device.
+ *
+ * The refcount of the returned bridge is incremented. Use drm_bridge_put()
+ * when done with it.
+ *
+ * Returns a pointer to the connected drm_bridge, or a negative error on failure
+ */
+struct drm_bridge *of_drm_get_bridge_by_endpoint(const struct device_node *np,
+						 int port, int endpoint)
+{
+	struct drm_bridge *bridge;
+
+	/*
+	 * of_graph_get_remote_node() produces a noisy error message if port
+	 * node isn't found and the absence of the port is a legit case here,
+	 * so at first we silently check whether graph presents in the
+	 * device-tree node.
+	 */
+	if (!of_graph_is_present(np))
+		return ERR_PTR(-ENODEV);
+
+	struct device_node *remote __free(device_node) =
+		of_graph_get_remote_node(np, port, endpoint);
+	if (!remote)
+		return ERR_PTR(-ENODEV);
+
+	bridge = of_drm_find_and_get_bridge(remote);
+	if (!bridge)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	return bridge;
+}
+EXPORT_SYMBOL_GPL(of_drm_get_bridge_by_endpoint);
 #endif
 
 /**
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index d6cd0f5af045..c96398460618 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -1327,6 +1327,8 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
 #ifdef CONFIG_OF
 struct drm_bridge *of_drm_find_and_get_bridge(struct device_node *np);
 struct drm_bridge *of_drm_find_bridge(struct device_node *np);
+struct drm_bridge *of_drm_get_bridge_by_endpoint(const struct device_node *np,
+						 int port, int endpoint);
 #else
 static inline struct drm_bridge *of_drm_find_and_get_bridge(struct device_node *np)
 {
@@ -1336,6 +1338,12 @@ static inline struct drm_bridge *of_drm_find_bridge(struct device_node *np)
 {
 	return NULL;
 }
+static inline int of_drm_get_bridge_by_endpoint(const struct device_node *np,
+						int port, int endpoint,
+						struct drm_bridge **bridge)
+{
+	return -ENODEV;
+}
 #endif
 
 static inline bool drm_bridge_is_last(struct drm_bridge *bridge)

-- 
2.53.0



^ permalink raw reply related

* [PATCH v3 03/11] drm/msm/hdmi: switch to of_drm_get_bridge_by_endpoint()
From: Luca Ceresoli @ 2026-04-28 15:30 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
	Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul,
	Marijn Suijten, Xinliang Liu, Sumit Semwal, Yongqin Liu,
	John Stultz, Tomi Valkeinen, Michal Simek
  Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, linux-arm-kernel, Luca Ceresoli
In-Reply-To: <20260428-drm-bridge-alloc-getput-panel_or_bridge-v3-0-a537b5567add@bootlin.com>

This driver calls drm_of_find_panel_or_bridge() with a NULL pointer in the
@panel parameter, thus using a reduced feature set of that function.
Replace this call with the simpler of_drm_get_bridge_by_endpoint().

Since of_drm_get_bridge_by_endpoint() increases the refcount of the
returned bridge, ensure it is put on removal.

Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>

---

Changes in v3:
- fix ERR_PTR deref when -ENODEV is returned
---
 drivers/gpu/drm/msm/hdmi/hdmi.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 852abb2466f0..124dedc084ec 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -287,9 +287,13 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev)
 	spin_lock_init(&hdmi->reg_lock);
 	mutex_init(&hdmi->state_mutex);
 
-	ret = drm_of_find_panel_or_bridge(dev_of_node(dev), 1, 0, NULL, &hdmi->next_bridge);
-	if (ret && ret != -ENODEV)
-		return ret;
+	hdmi->next_bridge = of_drm_get_bridge_by_endpoint(dev_of_node(dev), 1, 0);
+	if (IS_ERR(hdmi->next_bridge)) {
+		if (PTR_ERR(hdmi->next_bridge) == -ENODEV)
+			hdmi->next_bridge = NULL;
+		else
+			return PTR_ERR(hdmi->next_bridge);
+	}
 
 	hdmi->mmio = msm_ioremap(pdev, "core_physical");
 	if (IS_ERR(hdmi->mmio))
@@ -383,6 +387,7 @@ static void msm_hdmi_dev_remove(struct platform_device *pdev)
 	component_del(&pdev->dev, &msm_hdmi_ops);
 
 	msm_hdmi_put_phy(hdmi);
+	drm_bridge_put(hdmi->next_bridge);
 }
 
 static int msm_hdmi_runtime_suspend(struct device *dev)

-- 
2.53.0



^ permalink raw reply related

* Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
From: Shenwei Wang @ 2026-04-28 15:31 UTC (permalink / raw)
  To: Padhi, Beleswar, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski, Andrew Lunn
In-Reply-To: <32c119af-96ad-4da0-86f2-cdc4ba57ef0b@ti.com>



> -----Original Message-----
> From: Padhi, Beleswar <b-padhi@ti.com>
> Sent: Tuesday, April 28, 2026 10:11 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>; Linus Walleij
> <linusw@kernel.org>; Bartosz Golaszewski <brgl@kernel.org>; Jonathan Corbet
> <corbet@lwn.net>; Rob Herring <robh@kernel.org>; Krzysztof Kozlowski
> <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Bjorn Andersson
> <andersson@kernel.org>; Mathieu Poirier <mathieu.poirier@linaro.org>; Frank Li
> <frank.li@nxp.com>; Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Shuah Khan <skhan@linuxfoundation.org>; linux-gpio@vger.kernel.org; linux-
> doc@vger.kernel.org; linux-kernel@vger.kernel.org; Pengutronix Kernel Team
> <kernel@pengutronix.de>; Fabio Estevam <festevam@gmail.com>; Peng Fan
> <peng.fan@nxp.com>; devicetree@vger.kernel.org; linux-
> remoteproc@vger.kernel.org; imx@lists.linux.dev; linux-arm-
> kernel@lists.infradead.org; dl-linux-imx <linux-imx@nxp.com>; Bartosz
> Golaszewski <brgl@bgdev.pl>; Andrew Lunn <andrew@lunn.ch>
> Subject: Re: [EXT] Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg GPIO
> driver
>
> Caution: This is an external email. Please take care when clicking links or opening
> attachments. When in doubt, report the message using the 'Report this email'
> button
>
>
> On 4/28/2026 8:13 PM, Shenwei Wang wrote:
> >
> >> -----Original Message-----
> >> From: Beleswar Prasad Padhi <b-padhi@ti.com>
> >> Sent: Tuesday, April 28, 2026 2:25 AM
> >> To: Shenwei Wang <shenwei.wang@nxp.com>; Linus Walleij
> >> <linusw@kernel.org>; Bartosz Golaszewski <brgl@kernel.org>; Jonathan
> >> Corbet <corbet@lwn.net>; Rob Herring <robh@kernel.org>; Krzysztof
> >> Kozlowski <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>;
> >> Bjorn Andersson <andersson@kernel.org>; Mathieu Poirier
> >> <mathieu.poirier@linaro.org>; Frank Li <frank.li@nxp.com>; Sascha
> >> Hauer <s.hauer@pengutronix.de>
> >> Cc: Shuah Khan <skhan@linuxfoundation.org>;
> >> linux-gpio@vger.kernel.org; linux- doc@vger.kernel.org;
> >> linux-kernel@vger.kernel.org; Pengutronix Kernel Team
> >> <kernel@pengutronix.de>; Fabio Estevam <festevam@gmail.com>; Peng Fan
> >> <peng.fan@nxp.com>; devicetree@vger.kernel.org; linux-
> >> remoteproc@vger.kernel.org; imx@lists.linux.dev; linux-arm-
> >> kernel@lists.infradead.org; dl-linux-imx <linux-imx@nxp.com>; Bartosz
> >> Golaszewski <brgl@bgdev.pl>; Andrew Lunn <andrew@lunn.ch>
> >> Subject: [EXT] Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg
> >> GPIO driver On 28/04/26 00:53, Shenwei Wang wrote:
> >> [...]
> >>
> >>>>> +     void *channel_devices[MAX_PORT_PER_CHANNEL];
> >>>> So this is technically a rpmsg endpoint (struct rpmsg_endpoint)
> >>>> without naming it "endpoint". Every rpmsg endpoint has a reference
> >>>> to its parent rpmsg channel (struct rpmsg_device) which represents
> >>>> the same information here. So we should use the framework standard here.
> >>>>
> >>> Yes, agree to use "endpoint_devices".
> >>
> >> I did not mean to say to just change the variable name from
> >> "channel_devices" to "endpoint_devices". Infact you would not need to
> >> have this field & struct anymore.
> >>
> >> Pseudo-code:
> >> 1. Add a 'struct rpmsg_endpoint *ept' field to struct rpmsg_gpio_port
> >>      to maintain the ept to port idx map.
> >>
> >> 2. Call port->ept = rpmsg_create_ept(rpdev,
> >>                                                              rpmsg_gpio_channel_callback,
> >>                                                              port, {rpdev.id.name,
> >>                                                              RPMSG_ADDR_ANY,
> >>                                                              RPMSG_ADDR_ANY})
> >>      from rpmsg_gpiochip_register().
> >>
> > On the Linux side, we invoke rpmsg_create_ept. What is expected from the
> remote system in this case?
>
>
> Nothing extra in my opinion. rpmsg_create_ept() just creates a dynamic local
> endpoint address for Linux's usage. The firmware just has to make sure to reply
> to the same endpoint address where it received the message. This should already
> be in place IMO, because currently you are sending all messages in the default

Since rpmsg_create_ept creates a new local endpoint address on the Linux side, how is
the remote system expected to learn and use this new address for communication if no
additional logic is added on the remote side?

Is this handled automatically by the rpmsg stack software, or does it require explicit support
on the remote system to exchange and track endpoint addresses?

Thanks,
Shenwei

> endpoint (rpdev->ept) which is also dynamic[1] and is created when the channel
> is created. And you receive the responses correctly. (Unless you have hard-coded
> the default ept address in the firmware)
>
> [1]:
> https://github.co/
> m%2Ftorvalds%2Flinux%2Fblob%2Fmaster%2Fdrivers%2Frpmsg%2Frpmsg_core.
> c%23L480&data=05%7C02%7Cshenwei.wang%40nxp.com%7C4ec06bf01bb14dd
> 2625708dea5387471%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C6
> 39129859078622527%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRyd
> WUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%
> 3D%7C0%7C%7C%7C&sdata=OUmjqOdWqiXSTjPDv1TUvrjKP1YTx9ji44SdGlIR2n
> Q%3D&reserved=0
> (chinfo.src is RPMSG_ADDR_ANY)
>
> Thanks,
> Beleswar
>
> > If the remote side does not need any extra support, this would be an excellent
> solution.
> >
> > Thanks,
> > Shenwei
> >
> >> 3. Send msgs from local ept in rpmsg_gpio_send_message() by:
> >>      rpmsg_send(port->ept, msg, sizeof(*msg));
> >>
> >> 4. Get the port info in rpmsg_gpio_channel_callback() by:
> >>      struct rpmsg_gpio_port *port = priv;
> >>
> >> Which also eliminates the need for struct rpdev_drvdata as you can
> >> just do
> >> rpmsg_get_rproc_node_name(rpdev) from rpmsg_gpiochip_register().
> >>


^ permalink raw reply

* [PATCH v3 05/11] drm/bridge: chrontel-ch7033: switch to of_drm_get_bridge_by_endpoint()
From: Luca Ceresoli @ 2026-04-28 15:30 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
	Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul,
	Marijn Suijten, Xinliang Liu, Sumit Semwal, Yongqin Liu,
	John Stultz, Tomi Valkeinen, Michal Simek
  Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, linux-arm-kernel, Luca Ceresoli,
	Dmitry Baryshkov
In-Reply-To: <20260428-drm-bridge-alloc-getput-panel_or_bridge-v3-0-a537b5567add@bootlin.com>

This driver calls drm_of_find_panel_or_bridge() with a NULL pointer in the
@panel parameter, thus using a reduced feature set of that function.
Replace this call with the simpler of_drm_get_bridge_by_endpoint().

Since of_drm_get_bridge_by_endpoint() increases the refcount of the
returned bridge, ensure it is put on removal. To achieve this, instead of
adding an explicit drm_bridge_put(), migrate to the bridge::next_bridge
pointer which is automatically put when the bridge is eventually freed.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
 drivers/gpu/drm/bridge/chrontel-ch7033.c | 28 +++++++++++++---------------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/bridge/chrontel-ch7033.c b/drivers/gpu/drm/bridge/chrontel-ch7033.c
index 54d49d4882c8..a237c65ebd69 100644
--- a/drivers/gpu/drm/bridge/chrontel-ch7033.c
+++ b/drivers/gpu/drm/bridge/chrontel-ch7033.c
@@ -199,7 +199,6 @@ enum {
 
 struct ch7033_priv {
 	struct regmap *regmap;
-	struct drm_bridge *next_bridge;
 	struct drm_bridge bridge;
 	struct drm_connector connector;
 };
@@ -215,7 +214,7 @@ static enum drm_connector_status ch7033_connector_detect(
 {
 	struct ch7033_priv *priv = conn_to_ch7033_priv(connector);
 
-	return drm_bridge_detect(priv->next_bridge, connector);
+	return drm_bridge_detect(priv->bridge.next_bridge, connector);
 }
 
 static const struct drm_connector_funcs ch7033_connector_funcs = {
@@ -233,7 +232,7 @@ static int ch7033_connector_get_modes(struct drm_connector *connector)
 	const struct drm_edid *drm_edid;
 	int ret;
 
-	drm_edid = drm_bridge_edid_read(priv->next_bridge, connector);
+	drm_edid = drm_bridge_edid_read(priv->bridge.next_bridge, connector);
 	drm_edid_connector_update(connector, drm_edid);
 	if (drm_edid) {
 		ret = drm_edid_connector_add_modes(connector);
@@ -275,7 +274,7 @@ static int ch7033_bridge_attach(struct drm_bridge *bridge,
 	struct drm_connector *connector = &priv->connector;
 	int ret;
 
-	ret = drm_bridge_attach(encoder, priv->next_bridge, bridge,
+	ret = drm_bridge_attach(encoder, priv->bridge.next_bridge, bridge,
 				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 	if (ret)
 		return ret;
@@ -283,15 +282,15 @@ static int ch7033_bridge_attach(struct drm_bridge *bridge,
 	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
 		return 0;
 
-	if (priv->next_bridge->ops & DRM_BRIDGE_OP_DETECT) {
+	if (priv->bridge.next_bridge->ops & DRM_BRIDGE_OP_DETECT) {
 		connector->polled = DRM_CONNECTOR_POLL_HPD;
 	} else {
 		connector->polled = DRM_CONNECTOR_POLL_CONNECT |
 				    DRM_CONNECTOR_POLL_DISCONNECT;
 	}
 
-	if (priv->next_bridge->ops & DRM_BRIDGE_OP_HPD) {
-		drm_bridge_hpd_enable(priv->next_bridge, ch7033_hpd_event,
+	if (priv->bridge.next_bridge->ops & DRM_BRIDGE_OP_HPD) {
+		drm_bridge_hpd_enable(priv->bridge.next_bridge, ch7033_hpd_event,
 				      priv);
 	}
 
@@ -299,8 +298,8 @@ static int ch7033_bridge_attach(struct drm_bridge *bridge,
 				 &ch7033_connector_helper_funcs);
 	ret = drm_connector_init_with_ddc(bridge->dev, &priv->connector,
 					  &ch7033_connector_funcs,
-					  priv->next_bridge->type,
-					  priv->next_bridge->ddc);
+					  priv->bridge.next_bridge->type,
+					  priv->bridge.next_bridge->ddc);
 	if (ret) {
 		DRM_ERROR("Failed to initialize connector\n");
 		return ret;
@@ -313,8 +312,8 @@ static void ch7033_bridge_detach(struct drm_bridge *bridge)
 {
 	struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge);
 
-	if (priv->next_bridge->ops & DRM_BRIDGE_OP_HPD)
-		drm_bridge_hpd_disable(priv->next_bridge);
+	if (priv->bridge.next_bridge->ops & DRM_BRIDGE_OP_HPD)
+		drm_bridge_hpd_disable(priv->bridge.next_bridge);
 	drm_connector_cleanup(&priv->connector);
 }
 
@@ -543,10 +542,9 @@ static int ch7033_probe(struct i2c_client *client)
 
 	dev_set_drvdata(dev, priv);
 
-	ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL,
-					  &priv->next_bridge);
-	if (ret)
-		return ret;
+	priv->bridge.next_bridge = of_drm_get_bridge_by_endpoint(dev->of_node, 1, -1);
+	if (IS_ERR(priv->bridge.next_bridge))
+		return PTR_ERR(priv->bridge.next_bridge);
 
 	priv->regmap = devm_regmap_init_i2c(client, &ch7033_regmap_config);
 	if (IS_ERR(priv->regmap)) {

-- 
2.53.0



^ permalink raw reply related

* [PATCH v3 04/11] drm/hisilicon/kirin: switch to of_drm_get_bridge_by_endpoint()
From: Luca Ceresoli @ 2026-04-28 15:30 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
	Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul,
	Marijn Suijten, Xinliang Liu, Sumit Semwal, Yongqin Liu,
	John Stultz, Tomi Valkeinen, Michal Simek
  Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, linux-arm-kernel, Luca Ceresoli
In-Reply-To: <20260428-drm-bridge-alloc-getput-panel_or_bridge-v3-0-a537b5567add@bootlin.com>

This driver calls drm_of_find_panel_or_bridge() with a NULL pointer in the
@panel parameter, thus using a reduced feature set of that function.
Replace this call with the simpler of_drm_get_bridge_by_endpoint().

Since of_drm_get_bridge_by_endpoint() increases the refcount of the
returned bridge, ensure it is put on removal. Here the bridge pointer is
only stored in a temporary variable, so a cleanup action is enough.

Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
 drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
index e80debdc4176..ab3cd309505a 100644
--- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
+++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
@@ -778,17 +778,16 @@ static int dsi_host_init(struct device *dev, struct dw_dsi *dsi)
 static int dsi_bridge_init(struct drm_device *dev, struct dw_dsi *dsi)
 {
 	struct drm_encoder *encoder = &dsi->encoder;
-	struct drm_bridge *bridge;
+	struct drm_bridge *bridge __free(drm_bridge_put) = NULL;
 	struct device_node *np = dsi->dev->of_node;
-	int ret;
 
 	/*
 	 * Get the endpoint node. In our case, dsi has one output port1
 	 * to which the external HDMI bridge is connected.
 	 */
-	ret = drm_of_find_panel_or_bridge(np, 1, 0, NULL, &bridge);
-	if (ret)
-		return ret;
+	bridge = of_drm_get_bridge_by_endpoint(np, 1, 0);
+	if (IS_ERR(bridge))
+		return PTR_ERR(bridge);
 
 	/* associate the bridge to dsi encoder */
 	return drm_bridge_attach(encoder, bridge, NULL, 0);

-- 
2.53.0



^ permalink raw reply related

* [PATCH v3 06/11] drm/bridge: lontium-lt9611uxc: switch to of_drm_get_bridge_by_endpoint()
From: Luca Ceresoli @ 2026-04-28 15:30 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
	Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul,
	Marijn Suijten, Xinliang Liu, Sumit Semwal, Yongqin Liu,
	John Stultz, Tomi Valkeinen, Michal Simek
  Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, linux-arm-kernel, Luca Ceresoli,
	Dmitry Baryshkov
In-Reply-To: <20260428-drm-bridge-alloc-getput-panel_or_bridge-v3-0-a537b5567add@bootlin.com>

This driver calls drm_of_find_panel_or_bridge() with a NULL pointer in the
@panel parameter, thus using a reduced feature set of that function.
Replace this call with the simpler of_drm_get_bridge_by_endpoint().

Since of_drm_get_bridge_by_endpoint() increases the refcount of the
returned bridge, ensure it is put on removal. To achieve this, instead of
adding an explicit drm_bridge_put(), migrate to the bridge::next_bridge
pointer which is automatically put when the bridge is eventually freed.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
 drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
index 11aab07d88df..9427cc2358ae 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
@@ -35,7 +35,6 @@
 struct lt9611uxc {
 	struct device *dev;
 	struct drm_bridge bridge;
-	struct drm_bridge *next_bridge;
 
 	struct regmap *regmap;
 	/* Protects all accesses to registers by stopping the on-chip MCU */
@@ -284,7 +283,7 @@ static int lt9611uxc_bridge_attach(struct drm_bridge *bridge,
 {
 	struct lt9611uxc *lt9611uxc = bridge_to_lt9611uxc(bridge);
 
-	return drm_bridge_attach(encoder, lt9611uxc->next_bridge,
+	return drm_bridge_attach(encoder, lt9611uxc->bridge.next_bridge,
 				 bridge, flags);
 }
 
@@ -487,7 +486,11 @@ static int lt9611uxc_parse_dt(struct device *dev,
 
 	lt9611uxc->dsi1_node = of_graph_get_remote_node(dev->of_node, 1, -1);
 
-	return drm_of_find_panel_or_bridge(dev->of_node, 2, -1, NULL, &lt9611uxc->next_bridge);
+	lt9611uxc->bridge.next_bridge = of_drm_get_bridge_by_endpoint(dev->of_node, 2, -1);
+	if (IS_ERR(lt9611uxc->bridge.next_bridge))
+		return PTR_ERR(lt9611uxc->bridge.next_bridge);
+
+	return 0;
 }
 
 static int lt9611uxc_gpio_init(struct lt9611uxc *lt9611uxc)

-- 
2.53.0



^ permalink raw reply related

* [PATCH v3 08/11] drm/bridge: adv7511: switch to of_drm_get_bridge_by_endpoint()
From: Luca Ceresoli @ 2026-04-28 15:30 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
	Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul,
	Marijn Suijten, Xinliang Liu, Sumit Semwal, Yongqin Liu,
	John Stultz, Tomi Valkeinen, Michal Simek
  Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, linux-arm-kernel, Luca Ceresoli
In-Reply-To: <20260428-drm-bridge-alloc-getput-panel_or_bridge-v3-0-a537b5567add@bootlin.com>

This driver calls drm_of_find_panel_or_bridge() with a NULL pointer in the
@panel parameter, thus using a reduced feature set of that function.
Replace this call with the simpler of_drm_get_bridge_by_endpoint().

Since of_drm_get_bridge_by_endpoint() increases the refcount of the
returned bridge, ensure it is put on removal. To achieve this, instead of
adding an explicit drm_bridge_put(), migrate to the bridge::next_bridge
pointer which is automatically put when the bridge is eventually freed.

Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>

---

Changes in v3:
- fix ERR_PTR deref when -ENODEV is returned
---
 drivers/gpu/drm/bridge/adv7511/adv7511.h     |  1 -
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 15 +++++++++------
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 8be7266fd4f4..12c95198d9a4 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -354,7 +354,6 @@ struct adv7511 {
 	enum drm_connector_status status;
 	bool powered;
 
-	struct drm_bridge *next_bridge;
 	struct drm_display_mode curr_mode;
 
 	unsigned int f_tmds;
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 6bd76c1fb007..3c516551e482 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -851,8 +851,8 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge,
 	struct adv7511 *adv = bridge_to_adv7511(bridge);
 	int ret = 0;
 
-	if (adv->next_bridge) {
-		ret = drm_bridge_attach(encoder, adv->next_bridge, bridge,
+	if (adv->bridge.next_bridge) {
+		ret = drm_bridge_attach(encoder, adv->bridge.next_bridge, bridge,
 					flags | DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 		if (ret)
 			return ret;
@@ -1251,10 +1251,13 @@ static int adv7511_probe(struct i2c_client *i2c)
 
 	memset(&link_config, 0, sizeof(link_config));
 
-	ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL,
-					  &adv7511->next_bridge);
-	if (ret && ret != -ENODEV)
-		return ret;
+	adv7511->bridge.next_bridge = of_drm_get_bridge_by_endpoint(dev->of_node, 1, -1);
+	if (IS_ERR(adv7511->bridge.next_bridge)) {
+		if (PTR_ERR(adv7511->bridge.next_bridge) == -ENODEV)
+			adv7511->bridge.next_bridge = NULL;
+		else
+			return PTR_ERR(adv7511->bridge.next_bridge);
+	}
 
 	if (adv7511->info->link_config)
 		ret = adv7511_parse_dt(dev->of_node, &link_config);

-- 
2.53.0



^ permalink raw reply related

* [PATCH v3 07/11] drm/bridge: lt9611: switch to of_drm_get_bridge_by_endpoint()
From: Luca Ceresoli @ 2026-04-28 15:30 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
	Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul,
	Marijn Suijten, Xinliang Liu, Sumit Semwal, Yongqin Liu,
	John Stultz, Tomi Valkeinen, Michal Simek
  Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, linux-arm-kernel, Luca Ceresoli,
	Dmitry Baryshkov
In-Reply-To: <20260428-drm-bridge-alloc-getput-panel_or_bridge-v3-0-a537b5567add@bootlin.com>

This driver calls drm_of_find_panel_or_bridge() with a NULL pointer in the
@panel parameter, thus using a reduced feature set of that function.
Replace this call with the simpler of_drm_get_bridge_by_endpoint().

Since of_drm_get_bridge_by_endpoint() increases the refcount of the
returned bridge, ensure it is put on removal. To achieve this, instead of
adding an explicit drm_bridge_put(), migrate to the bridge::next_bridge
pointer which is automatically put when the bridge is eventually freed.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 4517aee83332..4b4418cc83bf 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -37,7 +37,6 @@
 struct lt9611 {
 	struct device *dev;
 	struct drm_bridge bridge;
-	struct drm_bridge *next_bridge;
 
 	struct regmap *regmap;
 
@@ -761,7 +760,7 @@ static int lt9611_bridge_attach(struct drm_bridge *bridge,
 {
 	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
 
-	return drm_bridge_attach(encoder, lt9611->next_bridge,
+	return drm_bridge_attach(encoder, lt9611->bridge.next_bridge,
 				 bridge, flags);
 }
 
@@ -1058,7 +1057,11 @@ static int lt9611_parse_dt(struct device *dev,
 
 	lt9611->ac_mode = of_property_read_bool(dev->of_node, "lt,ac-mode");
 
-	return drm_of_find_panel_or_bridge(dev->of_node, 2, -1, NULL, &lt9611->next_bridge);
+	lt9611->bridge.next_bridge = of_drm_get_bridge_by_endpoint(dev->of_node, 2, -1);
+	if (IS_ERR(lt9611->bridge.next_bridge))
+		return PTR_ERR(lt9611->bridge.next_bridge);
+
+	return 0;
 }
 
 static int lt9611_gpio_init(struct lt9611 *lt9611)

-- 
2.53.0



^ permalink raw reply related

* [PATCH v3 10/11] drm: zynqmp_dp: switch to of_drm_get_bridge_by_endpoint()
From: Luca Ceresoli @ 2026-04-28 15:30 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
	Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul,
	Marijn Suijten, Xinliang Liu, Sumit Semwal, Yongqin Liu,
	John Stultz, Tomi Valkeinen, Michal Simek
  Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, linux-arm-kernel, Luca Ceresoli
In-Reply-To: <20260428-drm-bridge-alloc-getput-panel_or_bridge-v3-0-a537b5567add@bootlin.com>

This driver calls drm_of_find_panel_or_bridge() with a NULL pointer in the
@panel parameter, thus using a reduced feature set of that function.
Replace this call with the simpler of_drm_get_bridge_by_endpoint().

Since of_drm_get_bridge_by_endpoint() increases the refcount of the
returned bridge, ensure it is put on removal. To achieve this, instead of
adding an explicit drm_bridge_put(), migrate to the bridge::next_bridge
pointer which is automatically put when the bridge is eventually freed.

Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>

---

Changes in v3:
- fix ERR_PTR deref when -ENODEV is returned
---
 drivers/gpu/drm/xlnx/zynqmp_dp.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
index 379180fb3004..c5aa236d6b74 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
@@ -353,7 +353,6 @@ struct zynqmp_dp_train_set_priv {
  * @lock: Mutex protecting this struct and register access (but not AUX)
  * @irq: irq
  * @bridge: DRM bridge for the DP encoder
- * @next_bridge: The downstream bridge
  * @test: Configuration for test mode
  * @config: IP core configuration from DTS
  * @aux: aux channel
@@ -385,7 +384,6 @@ struct zynqmp_dp {
 	struct completion aux_done;
 	struct mutex lock;
 
-	struct drm_bridge *next_bridge;
 	struct device *dev;
 	struct zynqmp_dpsub *dpsub;
 	void __iomem *iomem;
@@ -1494,8 +1492,8 @@ static int zynqmp_dp_bridge_attach(struct drm_bridge *bridge,
 		return ret;
 	}
 
-	if (dp->next_bridge) {
-		ret = drm_bridge_attach(encoder, dp->next_bridge,
+	if (dp->bridge.next_bridge) {
+		ret = drm_bridge_attach(encoder, dp->bridge.next_bridge,
 					bridge, flags);
 		if (ret < 0)
 			goto error;
@@ -2461,10 +2459,15 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub)
 	 * Acquire the next bridge in the chain. Ignore errors caused by port@5
 	 * not being connected for backward-compatibility with older DTs.
 	 */
-	ret = drm_of_find_panel_or_bridge(dp->dev->of_node, 5, 0, NULL,
-					  &dp->next_bridge);
-	if (ret < 0 && ret != -ENODEV)
-		goto err_reset;
+	dp->bridge.next_bridge = of_drm_get_bridge_by_endpoint(dp->dev->of_node, 5, 0);
+	if (IS_ERR(dp->bridge.next_bridge)) {
+		if (PTR_ERR(dp->bridge.next_bridge) == -ENODEV) {
+			dp->bridge.next_bridge;
+		} else {
+			ret = PTR_ERR(dp->bridge.next_bridge);
+			goto err_reset;
+		}
+	}
 
 	/* Initialize the hardware. */
 	dp->config.misc0 &= ~ZYNQMP_DP_MAIN_STREAM_MISC0_SYNC_LOCK;

-- 
2.53.0



^ permalink raw reply related

* [PATCH v3 09/11] drm/bridge: lt8713sx: switch to of_drm_get_bridge_by_endpoint()
From: Luca Ceresoli @ 2026-04-28 15:30 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
	Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul,
	Marijn Suijten, Xinliang Liu, Sumit Semwal, Yongqin Liu,
	John Stultz, Tomi Valkeinen, Michal Simek
  Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, linux-arm-kernel, Luca Ceresoli,
	Dmitry Baryshkov
In-Reply-To: <20260428-drm-bridge-alloc-getput-panel_or_bridge-v3-0-a537b5567add@bootlin.com>

This driver calls drm_of_find_panel_or_bridge() with a NULL pointer in the
@panel parameter, thus using a reduced feature set of that function.
Replace this call with the simpler of_drm_get_bridge_by_endpoint().

Since of_drm_get_bridge_by_endpoint() increases the refcount of the
returned bridge, ensure it is put on removal. To achieve this, instead of
adding an explicit drm_bridge_put(), migrate to the bridge::next_bridge
pointer which is automatically put when the bridge is eventually freed.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
 drivers/gpu/drm/bridge/lontium-lt8713sx.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt8713sx.c b/drivers/gpu/drm/bridge/lontium-lt8713sx.c
index 18fac6a46db4..cee485adf5e5 100644
--- a/drivers/gpu/drm/bridge/lontium-lt8713sx.c
+++ b/drivers/gpu/drm/bridge/lontium-lt8713sx.c
@@ -32,7 +32,6 @@ DECLARE_CRC8_TABLE(lt8713sx_crc_table);
 struct lt8713sx {
 	struct device *dev;
 	struct drm_bridge bridge;
-	struct drm_bridge *next_bridge;
 
 	struct regmap *regmap;
 	/* Protects all accesses to registers by stopping the on-chip MCU */
@@ -458,7 +457,7 @@ static int lt8713sx_bridge_attach(struct drm_bridge *bridge,
 	struct lt8713sx *lt8713sx = container_of(bridge, struct lt8713sx, bridge);
 
 	return drm_bridge_attach(encoder,
-				lt8713sx->next_bridge,
+				lt8713sx->bridge.next_bridge,
 				bridge, flags);
 }
 
@@ -537,10 +536,9 @@ static int lt8713sx_probe(struct i2c_client *client)
 	if (IS_ERR(lt8713sx->regmap))
 		return dev_err_probe(dev, PTR_ERR(lt8713sx->regmap), "regmap i2c init failed\n");
 
-	ret = drm_of_find_panel_or_bridge(lt8713sx->dev->of_node, 1, -1, NULL,
-					  &lt8713sx->next_bridge);
-	if (ret < 0)
-		return ret;
+	lt8713sx->bridge.next_bridge = of_drm_get_bridge_by_endpoint(lt8713sx->dev->of_node, 1, -1);
+	if (IS_ERR(lt8713sx->bridge.next_bridge))
+		return PTR_ERR(lt8713sx->bridge.next_bridge);
 
 	ret = lt8713sx_gpio_init(lt8713sx);
 	if (ret < 0)

-- 
2.53.0



^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox