Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/bridge: imx8qxp-pixel-link: get/put the next bridge

This driver obtains a bridge pointer from of_drm_find_bridge() in the probe
function and stores it until driver removal. of_drm_find_bridge() is
deprecated, so move to of_drm_find_and_get_bridge() for the bridge to be
refcounted and use bridge->next_bridge to put the reference on
deallocation.

To keep the code as simple and reliable as possible remove the intermediate
next_bridge and selected_bridge variables.

Get/put operations on the remaining pointer is pl->bridge.next_bridge,
which is tied to the struct imx8qxp_pixel_link lifetime, are:
- get reference when assigned (by of_drm_find_and_get_bridge())
- put reference before reassignment if reassignment happens
- put reference when the struct imx8qxp_pixel_link embedding the
struct drm_bridge is destroyed (struct drm_bridge::next_bridge)

Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Acked-by: Liu Ying <victor.liu@nxp.com>
Signed-off-by: Liu Ying <victor.liu@nxp.com>
Link: https://lore.kernel.org/r/20260211-drm-bridge-alloc-getput-drm_of_find_bridge-v6-1-651ddfd13bdb@bootlin.com

authored by

Luca Ceresoli and committed by
Liu Ying
b99deb61 645186bf

+13 -14
+13 -14
drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c
··· 23 23 24 24 struct imx8qxp_pixel_link { 25 25 struct drm_bridge bridge; 26 - struct drm_bridge *next_bridge; 27 26 struct device *dev; 28 27 struct imx_sc_ipc *ipc_handle; 29 28 u8 stream_id; ··· 139 140 } 140 141 141 142 return drm_bridge_attach(encoder, 142 - pl->next_bridge, bridge, 143 + pl->bridge.next_bridge, bridge, 143 144 DRM_BRIDGE_ATTACH_NO_CONNECTOR); 144 145 } 145 146 ··· 259 260 { 260 261 struct device_node *np = pl->dev->of_node; 261 262 struct device_node *port; 262 - struct drm_bridge *selected_bridge = NULL; 263 263 u32 port_id; 264 264 bool found_port = false; 265 265 int reg; ··· 295 297 continue; 296 298 } 297 299 298 - struct drm_bridge *next_bridge = of_drm_find_bridge(remote); 299 - if (!next_bridge) 300 - return -EPROBE_DEFER; 301 - 302 - /* 303 - * Select the next bridge with companion PXL2DPI if 304 - * present, otherwise default to the first bridge 305 - */ 306 - if (!selected_bridge || of_property_present(remote, "fsl,companion-pxl2dpi")) 307 - selected_bridge = next_bridge; 300 + if (!pl->bridge.next_bridge) { 301 + /* Select the first bridge by default... */ 302 + pl->bridge.next_bridge = of_drm_find_and_get_bridge(remote); 303 + if (!pl->bridge.next_bridge) 304 + return -EPROBE_DEFER; 305 + } else if (of_property_present(remote, "fsl,companion-pxl2dpi")) { 306 + /* ... but prefer the companion PXL2DPI if present */ 307 + drm_bridge_put(pl->bridge.next_bridge); 308 + pl->bridge.next_bridge = of_drm_find_and_get_bridge(remote); 309 + if (!pl->bridge.next_bridge) 310 + return -EPROBE_DEFER; 311 + } 308 312 } 309 313 310 314 pl->mst_addr = port_id - 1; 311 - pl->next_bridge = selected_bridge; 312 315 313 316 return 0; 314 317 }