All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Luca Ceresoli" <luca.ceresoli@bootlin.com>
To: "Maxime Ripard" <mripard@kernel.org>,
	"Luca Ceresoli" <luca.ceresoli@bootlin.com>
Cc: "Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Thomas Zimmermann" <tzimmermann@suse.de>,
	"David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>,
	"Andrzej Hajda" <andrzej.hajda@intel.com>,
	"Neil Armstrong" <neil.armstrong@linaro.org>,
	"Robert Foss" <rfoss@kernel.org>,
	"Laurent Pinchart" <Laurent.pinchart@ideasonboard.com>,
	"Jonas Karlman" <jonas@kwiboo.se>,
	"Jernej Skrabec" <jernej.skrabec@gmail.com>,
	"Jessica Zhang" <jesszhan0024@gmail.com>,
	"Linus Walleij" <linusw@kernel.org>,
	"Inki Dae" <inki.dae@samsung.com>,
	"Jagan Teki" <jagan@amarulasolutions.com>,
	"Marek Szyprowski" <m.szyprowski@samsung.com>,
	"Dmitry Baryshkov" <dmitry.baryshkov@oss.qualcomm.com>,
	"Hui Pu" <Hui.Pu@gehealthcare.com>,
	"Ian Ray" <ian.ray@gehealthcare.com>,
	"Thomas Petazzoni" <thomas.petazzoni@bootlin.com>,
	<dri-devel@lists.freedesktop.org>, <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 05/11] drm/bridge: panel: add a panel_bridge to every panel
Date: Mon, 17 Aug 2026 14:30:27 +0200	[thread overview]
Message-ID: <DKR7XPSEOSUB.2E7CFACFXZ2WE@bootlin.com> (raw)
In-Reply-To: <20260817-cuddly-loyal-swan-075985@houat>

Hi Maxime,

On Mon Aug 17, 2026 at 10:42 AM CEST, Maxime Ripard wrote:
> On Fri, Aug 14, 2026 at 04:05:53PM +0200, Luca Ceresoli wrote:
>> Adding a panel does currently not add a panel_bridge wrapping it. Usually
>> the panel_bridge creation happens later, when some other driver (e.g. the
>> previous bridge or the encoder) calls *_of_get_bridge() and the following
>> element in the pipeline is a panel.
>>
>> This has some drawbacks:
>>
>>  * hte bridge API is currently the best practice to access various
>>    components of the pipeline, especially with complex cards where bridges
>>    can be combined in different ways on different hardware
>>  * the panel_bridge is not created in the context of the driver of the
>>    underlying physical device (the panel driver), but of some other driver
>>  * that other driver is not aware of whether the returned drm_bridge
>>    pointer is a panel_bridge created on the fly, a pre-existing
>>    panel_bridge or a non-panel bridge
>>  * removal of a panel_bridge requires calling drm_panel_bridge_remove(),
>>    but the other driver doesn't know whether this is needed because it
>>    doesn't know whether it has created a panel_bridge or not
>>
>> So far the current approach has been working because devm and drmm ensure
>> the panel bridge would be dealloacted at some later point. However with the
>> upcoming implementation of dynamic bridge lifetime this will get more
>> complicated.
>>
>> Switch to the new approach: always create a panel_bridge with a drm_panel,
>> thus matching the lifetime of the drm_panel and the panel_bridge wrapping
>> it. This makes lifetime much more straightforward to understand and to
>> further develop on.
>>
>> As a consequence devm_drm_of_get_bridge() and drmm_of_get_bridge() don't
>> need to look for a panel anymore and become simple wrappers to
>> of_drm_get_bridge_by_endpoint(). Also deprecate them as they can be
>> replaced by of_drm_get_bridge_by_endpoint() which also handles refcount.
>>
>> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
>> ---
>>  drivers/gpu/drm/bridge/panel.c | 47 +++++++++++++++++++++---------------------
>>  drivers/gpu/drm/drm_panel.c    |  3 +++
>>  include/drm/drm_panel.h        |  8 +++++++
>>  3 files changed, 34 insertions(+), 24 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
>> index 02388a3de626..d86555254aa9 100644
>> --- a/drivers/gpu/drm/bridge/panel.c
>> +++ b/drivers/gpu/drm/bridge/panel.c
>> @@ -412,6 +412,11 @@ struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev,
>>  {
>>  	struct drm_bridge **ptr, *bridge;
>>
>> +	if (panel->bridge) {
>> +		dev_dbg(dev, "returning existing bridge=%p\n", panel->bridge);
>> +		return panel->bridge;
>> +	}
>> +
>>  	ptr = devres_alloc(devm_drm_panel_bridge_release, sizeof(*ptr),
>>  			   GFP_KERNEL);
>>  	if (!ptr)
>> @@ -495,9 +500,12 @@ EXPORT_SYMBOL(drm_panel_bridge_connector);
>>   * @port: port in the device tree node
>>   * @endpoint: endpoint in the device tree node
>>   *
>> + * This function is deprecated and should not be used in new drivers. The
>> + * returned bridge refcount is not incremented! Replace by
>> + * of_drm_get_bridge_by_endpoint() and handle bridge refcount.
>> + *
>>   * Given a DT node's port and endpoint number, finds the connected node
>> - * and returns the associated bridge if any, or creates and returns a
>> - * drm panel bridge instance if a panel is connected.
>> + * and returns the associated bridge if any.
>>   *
>>   * Returns a pointer to the bridge if successful, or an error pointer
>>   * otherwise.
>> @@ -507,18 +515,12 @@ struct drm_bridge *devm_drm_of_get_bridge(struct device *dev,
>>  					  u32 port, u32 endpoint)
>>  {
>>  	struct drm_bridge *bridge;
>> -	struct drm_panel *panel;
>> -	int ret;
>>
>> -	ret = drm_of_find_panel_or_bridge(np, port, endpoint,
>> -					  &panel, &bridge);
>> -	if (ret)
>> -		return ERR_PTR(ret);
>> +	bridge = of_drm_get_bridge_by_endpoint(np, port, endpoint);
>> +	if (IS_ERR(bridge))
>> +		return bridge;
>>
>> -	if (panel) {
>> -		bridge = devm_drm_panel_bridge_add(dev, panel);
>> -		drm_panel_put(panel);
>> -	}
>> +	drm_bridge_put(bridge);
>>
>>  	return bridge;
>>  }
>> @@ -531,9 +533,12 @@ EXPORT_SYMBOL(devm_drm_of_get_bridge);
>>   * @port: port in the device tree node
>>   * @endpoint: endpoint in the device tree node
>>   *
>> + * This function is deprecated and should not be used in new drivers. The
>> + * returned bridge refcount is not incremented! Replace by
>> + * of_drm_get_bridge_by_endpoint() and handle bridge refcount.
>> + *
>>   * Given a DT node's port and endpoint number, finds the connected node
>> - * and returns the associated bridge if any, or creates and returns a
>> - * drm panel bridge instance if a panel is connected.
>> + * and returns the associated bridge if any.
>>   *
>>   * Returns a drmm managed pointer to the bridge if successful, or an error
>>   * pointer otherwise.
>> @@ -543,18 +548,12 @@ struct drm_bridge *drmm_of_get_bridge(struct drm_device *drm,
>>  				      u32 port, u32 endpoint)
>>  {
>>  	struct drm_bridge *bridge;
>> -	struct drm_panel *panel;
>> -	int ret;
>>
>> -	ret = drm_of_find_panel_or_bridge(np, port, endpoint,
>> -					  &panel, &bridge);
>> -	if (ret)
>> -		return ERR_PTR(ret);
>> +	bridge = of_drm_get_bridge_by_endpoint(np, port, endpoint);
>> +	if (IS_ERR(bridge))
>> +		return bridge;
>>
>> -	if (panel) {
>> -		bridge = drmm_panel_bridge_add(drm, panel);
>> -		drm_panel_put(panel);
>> -	}
>> +	drm_bridge_put(bridge);
>>
>>  	return bridge;
>>  }
>> diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
>> index f8f6082e637f..95fc95d1b4b7 100644
>> --- a/drivers/gpu/drm/drm_panel.c
>> +++ b/drivers/gpu/drm/drm_panel.c
>> @@ -453,6 +453,9 @@ void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t offset,
>>
>>  	drm_panel_init(panel, dev, funcs, connector_type);
>>
>> +	panel->bridge = devm_drm_panel_bridge_add(dev, panel);
>> +	WARN_ON(!panel->bridge);
>> +
>
> Having two refcounted dynamic allocations yet with the exact same
> lifetime makes me a bit uneasy: we'll introduce lifetime / reference
> count issue because we would then have to keep the same reference count
> everywhere.

It may look twisty but I don't see why it should not work.

> I wonder if we shouldn't embed the drm_bridge struct into drm_panel, and
> provide a way for the drm_panel and drm_bridge to share the same
> refcount, maybe by making drm_panel_get take drm_bridge.refcount instead
> of duplicating the refcount in both drm_panel and drm_bridge?

That is the other option I evaluated, and I must agree it makes
sense. Basically the resulting bridge refcount would be:

  bridge.refcount == number of drm_bridge_get() calls
                   + number of drm_panel_get() calls
		   - number of drm_bridge_put() calls
                   - number of drm_panel_put() calls

I think that's an implementation detail, even though an important one. The
API for both panel and bridge users would be the same, and with the same
guarantee: memory won't be freed before (get - put) reaches zero, but with
the second idea it could be freed even later.

I'll try implementing this, and see what happens when going into the
details.

Luca

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

  reply	other threads:[~2026-08-17 12:30 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-14 14:05 [PATCH 00/11] drm/panel: add a panel_bridge to every panel Luca Ceresoli
2026-08-14 14:05 ` [PATCH 01/11] drm: of: drm_of_find_panel_or_bridge: simplify freeing the remote node pointer Luca Ceresoli
2026-08-17  8:21   ` Maxime Ripard
2026-08-14 14:05 ` [PATCH 02/11] drm: of: drm_of_find_panel_or_bridge: simplify error return paths Luca Ceresoli
2026-08-17  8:23   ` Maxime Ripard
2026-08-14 14:05 ` [PATCH 03/11] drm: of: drm_of_find_panel_or_bridge: prioritize the bridge, not the panel Luca Ceresoli
2026-08-14 14:20   ` sashiko-bot
2026-08-17  8:26   ` Maxime Ripard
2026-08-17 12:23     ` Luca Ceresoli
2026-08-14 14:05 ` [PATCH 04/11] drm/panel: merge the drm_kms_helper module into the drm module Luca Ceresoli
2026-08-14 14:13   ` sashiko-bot
2026-08-17  8:31   ` Maxime Ripard
2026-08-17 12:27     ` Luca Ceresoli
2026-08-14 14:05 ` [PATCH 05/11] drm/bridge: panel: add a panel_bridge to every panel Luca Ceresoli
2026-08-14 14:25   ` sashiko-bot
2026-08-17 14:07     ` Luca Ceresoli
2026-08-17  8:42   ` Maxime Ripard
2026-08-17 12:30     ` Luca Ceresoli [this message]
2026-08-14 14:05 ` [PATCH 06/11] drm/bridge: tc358767: don't create a panel_bridge Luca Ceresoli
2026-08-14 14:17   ` sashiko-bot
2026-08-14 14:05 ` [PATCH 07/11] drm/bridge: waveshare-dsi: " Luca Ceresoli
2026-08-14 14:05 ` [PATCH 08/11] drm/mcde: dsi: simplify device_node management using scoped for_each variant Luca Ceresoli
2026-08-14 14:19   ` sashiko-bot
2026-08-17  8:43   ` Maxime Ripard
2026-08-17 12:25   ` Linus Walleij
2026-08-17 12:34     ` Luca Ceresoli
2026-08-14 14:05 ` [PATCH 09/11] drm/mcde: dsi: don't create a panel_bridge Luca Ceresoli
2026-08-14 14:24   ` sashiko-bot
2026-08-17 12:23   ` Linus Walleij
2026-08-14 14:05 ` [PATCH 10/11] drm/bridge: fsl-ldb: " Luca Ceresoli
2026-08-14 14:18   ` sashiko-bot
2026-08-14 14:05 ` [PATCH 11/11] drm/bridge: samsung-dsim: " Luca Ceresoli
2026-08-14 14:23   ` sashiko-bot
2026-08-14 14:13 ` [PATCH 00/11] drm/panel: add a panel_bridge to every panel Luca Ceresoli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=DKR7XPSEOSUB.2E7CFACFXZ2WE@bootlin.com \
    --to=luca.ceresoli@bootlin.com \
    --cc=Hui.Pu@gehealthcare.com \
    --cc=Laurent.pinchart@ideasonboard.com \
    --cc=airlied@gmail.com \
    --cc=andrzej.hajda@intel.com \
    --cc=dmitry.baryshkov@oss.qualcomm.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=ian.ray@gehealthcare.com \
    --cc=inki.dae@samsung.com \
    --cc=jagan@amarulasolutions.com \
    --cc=jernej.skrabec@gmail.com \
    --cc=jesszhan0024@gmail.com \
    --cc=jonas@kwiboo.se \
    --cc=linusw@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=neil.armstrong@linaro.org \
    --cc=rfoss@kernel.org \
    --cc=simona@ffwll.ch \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.