On Mon Jun 8, 2026 at 1:53 PM CEST, Maxime Ripard wrote:
> On Tue, May 19, 2026 at 12:37:35PM +0200, Luca Ceresoli wrote:
>> In preparation for DRM bridge hot-plugging, we need to handle the dynamic
>> lifetime of the following bridge in case the samsung-dsim is always present
>> and the following bridge (next_bridge) is hot-unplugged.
>>
>> Based on the 'if (!IS_ERR(panel))' check in samsung_dsim_host_attach(), the
>> next_bridge could be A) a panel bridge created by this driver via
>> devm_drm_panel_bridge_add() or B) a pre-existing bridge obtained via
>> of_drm_find_and_get_bridge().
>>
>> For case B) we need to put that reference when the next_bridge is removed,
>> which is already handled by calling drm_bridge_clear_and_put() in
>> samsung_dsim_host_detach() and in the samsung_dsim_host_attach() error
>> management code.
>>
>> In case A) we additionally have to remove the panel bridge. Currently it is
>> created by devm_drm_panel_bridge_add(), which adds two devm actions with
>> the refcounted panel bridge:
>>
>>  - drm_bridge_put_void() via devm_drm_bridge_alloc() on panel->dev
>>  - devm_drm_panel_bridge_release() via devm_drm_panel_bridge_add_typed()
>>    on the consumer device (samsung-dsim)
>>
>> The first action is OK: being tied to panel->dev it will happen when the
>> panel is unplugged.
>>
>> The second action is bound to the consumer device, so the devm semantics is
>> not useful here when introducing hotplug. Indeed we need to drop the
>> next_bridge in samsung_dsim_host_detach() anyway, before the driver .remove
>> function, in order to support {add, {attach, detach} x N, remove} hotplug
>> event sequences.
>>
>> Thus move to the non-devm drm_panel_bridge_add() along with the matching
>> drm_panel_bridge_remove(), so the lifetime of the panel-bridge is tied to
>> the host_attach/host_detach cycle and not the whole samsung-dsim device
>> lifetime.
>>
>> Signed-off-by: Luca Ceresoli <[email protected]>
>>
>> ---
>>
>> In a previous discussion with Maxime he mentioned a plan to make every
>> drm_panel always have a wrapping bridge. With that done, all the code
>> handling the panel and adding the panel_bridge would become useless here
>> (and in many other places) and could be entirely removed. This patch is a
>> temporary solution until that happens. The best pointer I could find to
>> that discussion is [0], but there might be more recent material I could not
>> find at the moment.
>>
>> [0] https://lore.kernel.org/lkml/20250218-faithful-white-magpie-da9ac9@houat/
>> ---
>>  drivers/gpu/drm/bridge/samsung-dsim.c | 17 ++++++++++++++---
>>  include/drm/bridge/samsung-dsim.h     |  2 ++
>>  2 files changed, 16 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
>> b/drivers/gpu/drm/bridge/samsung-dsim.c
>> index 5b799619e07e..2af287221e22 100644
>> --- a/drivers/gpu/drm/bridge/samsung-dsim.c
>> +++ b/drivers/gpu/drm/bridge/samsung-dsim.c
>> @@ -1951,14 +1951,16 @@ static int samsung_dsim_host_attach(struct 
>> mipi_dsi_host *host,
>>      if (!remote)
>>              return -ENODEV;
>>
>> +    dsi->panel_bridge_added = false;
>>      panel = of_drm_find_panel(remote);
>>      if (!IS_ERR(panel)) {
>> -            next_bridge = devm_drm_panel_bridge_add(dev, panel);
>> +            next_bridge = drm_panel_bridge_add(panel);
>>              if (IS_ERR(next_bridge)) {
>>                      ret = PTR_ERR(next_bridge);
>>                      next_bridge = NULL; // Inhibit the cleanup action on an 
>> ERR_PTR
>>              } else {
>>                      drm_bridge_get(next_bridge);
>> +                    dsi->panel_bridge_added = true;
>>              }
>>      } else {
>>              next_bridge = of_drm_find_and_get_bridge(remote);
>> @@ -1989,7 +1991,7 @@ static int samsung_dsim_host_attach(struct 
>> mipi_dsi_host *host,
>>      if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
>>              ret = samsung_dsim_register_te_irq(dsi, &device->dev);
>>              if (ret)
>> -                    goto err_remove_bridge;
>> +                    goto err_remove_panel_bridge;
>>      }
>>
>>      // The next bridge can be used by host_ops->attach
>> @@ -2011,8 +2013,12 @@ static int samsung_dsim_host_attach(struct 
>> mipi_dsi_host *host,
>>      drm_bridge_clear_and_put(&dsi->bridge.next_bridge);
>>      if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO))
>>              samsung_dsim_unregister_te_irq(dsi);
>> -err_remove_bridge:
>> +err_remove_panel_bridge:
>>      drm_bridge_remove(&dsi->bridge);
>> +    if (dsi->panel_bridge_added) {
>> +            drm_panel_bridge_remove(next_bridge);
>> +            dsi->panel_bridge_added = false;
>> +    }
>
> This is a pretty big abstraction leak. We don't want to have that in
> everything driver. The removal path should be the same for both cases,
> and it's not something the driver should take care of.

Yes. The comment after the '---' separator was meant to discuss this
concern:

> In a previous discussion with Maxime he mentioned a plan to make every
> drm_panel always have a wrapping bridge. With that done, all the code
> handling the panel and adding the panel_bridge would become useless here
> (and in many other places) and could be entirely removed. This patch is a
> temporary solution until that happens. The best pointer I could find to
> that discussion is [0], but there might be more recent material I could not
> find at the moment.

Do you have any update about that plan?

Luca

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

Reply via email to