All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Luca Ceresoli" <luca.ceresoli@bootlin.com>
To: "H. Nikolaus Schaller" <hns@goldelico.com>,
	"Paul Cercueil" <paul@crapouillou.net>
Cc: "Florian Fainelli" <f.fainelli@gmail.com>,
	<linux-kernel@vger.kernel.org>,
	"Paul Boddie" <paul@boddie.org.uk>,
	"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Maxime Ripard" <mripard@kernel.org>,
	"Thomas Zimmermann" <tzimmermann@suse.de>,
	"David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>,
	"Luca Ceresoli" <luca.ceresoli@bootlin.com>,
	"open list:INGENIC JZ47xx SoCs" <linux-mips@vger.kernel.org>,
	"open list:DRM DRIVERS" <dri-devel@lists.freedesktop.org>,
	"Discussions about the Letux Kernel"
	<letux-kernel@openphoenux.org>,
	"Thomas Petazzoni" <thomas.petazzoni@bootlin.com>
Subject: Re: [PATCH] drm/ingenic: Allocate and register the internal bridge separately
Date: Fri, 06 Nov 2026 14:51:33 +0100	[thread overview]
Message-ID: <DMO6DXVL3192.142ATKP8CWVXD@bootlin.com> (raw)
In-Reply-To: <80369640-E1F7-489A-B25B-69B83061C8DE@goldelico.com>

Hello all,

On Fri Nov 6, 2026 at 1:28 PM CET, H. Nikolaus Schaller wrote:
>
>
>> Am 06.11.2026 um 13:21 schrieb Paul Cercueil <paul@crapouillou.net>:
>>
>> Nikolaus:
>>
>> Le vendredi 06 novembre 2026 à 11:59 +0100, H. Nikolaus Schaller a écrit :
>>> Hi,
>>>
>>>> Am 05.11.2026 um 21:35 schrieb Florian Fainelli <f.fainelli@gmail.com>:
>>>>
>>>> The LCD controller's internal bridge is embedded in an object allocated
>>>> with drmm_encoder_alloc(). This initializes the encoder but leaves the
>>>> bridge's reference count at zero. Since drm_bridge_attach() takes a
>>>> reference, probing the CI20 display produces addition-on-zero and
>>>> underflow warnings and fails to attach the HDMI bridge chain.
>>>>
>>>> Allocate the internal bridge with devm_drm_bridge_alloc() and register
>>>> it with devm_drm_bridge_add() before attaching it. Keep the encoder in a
>>>> separate DRM-managed allocation: encoder cleanup can drop the final
>>>> bridge reference before it has finished accessing the encoder. Find
>>>> the internal bridge through the encoder's bridge chain during mode
>>>> setting, and use the bridge argument directly in bridge callbacks.
>>>>
>>>> Fixes: 94d50c1a2ca3 ("drm/bridge: get/put the bridge reference in
>>>> drm_bridge_attach/detach()")
>>>> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
>>>> ---
>>>> drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 31 +++++++++++++++--------
>>>> 1 file changed, 21 insertions(+), 10 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
>>>> b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
>>>> index 625ec76cf04d..520912f9ed0d 100644
>>>> --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
>>>> +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
>>>> @@ -121,16 +121,15 @@ struct ingenic_drm {
>>>> };
>>>>
>>>> struct ingenic_drm_bridge {
>>>> - struct drm_encoder encoder;
>>>> struct drm_bridge bridge, *next_bridge;
>>>>
>>>> struct drm_bus_cfg bus_cfg;
>>>> };
>>>>
>>>> static inline struct ingenic_drm_bridge *
>>>> -to_ingenic_drm_bridge(struct drm_encoder *encoder)
>>>> +to_ingenic_drm_bridge(struct drm_bridge *bridge)
>>>> {
>>>> - return container_of(encoder, struct ingenic_drm_bridge, encoder);
>>>> + return container_of(bridge, struct ingenic_drm_bridge, bridge);
>>>> }
>>>>
>>>> static inline struct ingenic_drm_private_state *
>>>> @@ -738,7 +737,9 @@ static void ingenic_drm_encoder_atomic_mode_set(struct
>>>> drm_encoder *encoder,
>>>> {
>>>> struct ingenic_drm *priv = drm_device_get_priv(encoder->dev);
>>>> struct drm_display_mode *mode = &crtc_state->adjusted_mode;
>>>> - struct ingenic_drm_bridge *bridge = to_ingenic_drm_bridge(encoder);
>>>> + struct drm_bridge *first_bridge __free(drm_bridge_put) =
>>>> + drm_bridge_chain_get_first_bridge(encoder);
>>>> + struct ingenic_drm_bridge *bridge = to_ingenic_drm_bridge(first_bridge);
>>>> unsigned int cfg, rgbcfg = 0;
>>>>
>>>> priv->panel_is_sharp = bridge->bus_cfg.flags & DRM_BUS_FLAG_SHARP_SIGNALS;
>>>> @@ -799,7 +800,7 @@ static int ingenic_drm_bridge_attach(struct drm_bridge
>>>> *bridge,
>>>>     struct drm_encoder *encoder,
>>>>     enum drm_bridge_attach_flags flags)
>>>> {
>>>> - struct ingenic_drm_bridge *ib = to_ingenic_drm_bridge(encoder);
>>>> + struct ingenic_drm_bridge *ib = to_ingenic_drm_bridge(bridge);
>>>>
>>>> return drm_bridge_attach(encoder, ib->next_bridge,
>>>> &ib->bridge, flags);
>>>> @@ -811,7 +812,7 @@ static int ingenic_drm_bridge_atomic_check(struct
>>>> drm_bridge *bridge,
>>>>   struct drm_connector_state *conn_state)
>>>> {
>>>> struct drm_display_mode *mode = &crtc_state->adjusted_mode;
>>>> - struct ingenic_drm_bridge *ib = to_ingenic_drm_bridge(bridge->encoder);
>>>> + struct ingenic_drm_bridge *ib = to_ingenic_drm_bridge(bridge);
>>>>
>>>> ib->bus_cfg = bridge_state->output_bus_cfg;
>>>>
>>>> @@ -1303,22 +1304,32 @@ static int ingenic_drm_bind(struct device *dev, bool
>>>> has_components)
>>>> drm_panel_put(panel);
>>>> }
>>>>
>>>> - ib = drmm_encoder_alloc(drm, struct ingenic_drm_bridge, encoder,
>>>> - NULL, DRM_MODE_ENCODER_DPI, NULL);
>>>> + ib = devm_drm_bridge_alloc(dev, struct ingenic_drm_bridge, bridge,
>>>> +   &ingenic_drm_bridge_funcs);
>>>> if (IS_ERR(ib)) {
>>>> ret = PTR_ERR(ib);
>>>> + dev_err(dev, "Failed to allocate bridge: %d\n", ret);
>>>> + goto err_drvdata;
>>>> + }
>>>> +
>>>> + encoder = drmm_plain_encoder_alloc(drm, NULL,
>>>> +   DRM_MODE_ENCODER_DPI, NULL);
>>>> + if (IS_ERR(encoder)) {
>>>> + ret = PTR_ERR(encoder);
>>>> dev_err(dev, "Failed to init encoder: %d\n", ret);
>>>> goto err_drvdata;
>>>> }
>>>>
>>>> - encoder = &ib->encoder;
>>>> encoder->possible_crtcs = drm_crtc_mask(&priv->crtc);
>>>>
>>>> drm_encoder_helper_add(encoder, &ingenic_drm_encoder_helper_funcs);
>>>>
>>>> - ib->bridge.funcs = &ingenic_drm_bridge_funcs;
>>>> ib->next_bridge = bridge;
>>>>
>>>> + ret = devm_drm_bridge_add(dev, &ib->bridge);
>>>> + if (ret)
>>>> + goto err_drvdata;
>>>> +
>>>> ret = drm_bridge_attach(encoder, &ib->bridge, NULL,
>>>> DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>> if (ret) {
>>>> --
>>>> 2.53.0
>>>
>>> Works for me on CI20 with HDMI display.
>>>
>>> Tested-by: H. Nikolaus Schaller <hns@goldelico.com> # CI20 V2a
>>
>> This patches basically overrides your "[PATCH v6] drm/ingenic: fix bridge
>> allocation", correct?
>
> Indeed.
>
> Well, I am not sure which is the right one. Both work for me. So you can choose
> (e.g. if struct ingenic_drm_bridge should embed an struct drm_encoder encoder
> or not.

Sorry I hadn't seen the previous patches by Nikolaus. And I missed this
driver while converting bridge users to devm_drm_bridge_alloc().

Both patches look technically correct, but this one looks cleaner to me, so
I'd apply this one.

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

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

  reply	other threads:[~2026-11-06 13:51 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05 20:35 [PATCH] drm/ingenic: Allocate and register the internal bridge separately Florian Fainelli
2026-11-06 10:59 ` H. Nikolaus Schaller
2026-11-06 12:21   ` Paul Cercueil
2026-11-06 12:28     ` H. Nikolaus Schaller
2026-11-06 13:51       ` Luca Ceresoli [this message]
2026-11-09 19:46 ` Paul Cercueil
2026-11-10 14:39   ` Luca Ceresoli
2026-11-10 14:45   ` Maxime Ripard
2026-11-10 17:05     ` Paul Cercueil

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=DMO6DXVL3192.142ATKP8CWVXD@bootlin.com \
    --to=luca.ceresoli@bootlin.com \
    --cc=airlied@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=f.fainelli@gmail.com \
    --cc=hns@goldelico.com \
    --cc=letux-kernel@openphoenux.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=paul@boddie.org.uk \
    --cc=paul@crapouillou.net \
    --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.