On Fri, Feb 3, 2023 at 1:56 PM Maxime Ripard <maxime@xxxxxxxxxx> wrote: > > On Thu, Feb 02, 2023 at 10:22:42PM +0530, Jagan Teki wrote: > > Hi Maxime, > > > > On Mon, Jan 30, 2023 at 6:28 PM Maxime Ripard <maxime@xxxxxxxxxx> wrote: > > > > > > On Thu, Jan 26, 2023 at 08:48:48PM +0530, Jagan Teki wrote: > > > > On Thu, Jan 26, 2023 at 5:42 PM Maxime Ripard <maxime@xxxxxxxxxx> wrote: > > > > > > > > > > Hi, > > > > > > > > > > On Mon, Jan 23, 2023 at 08:41:56PM +0530, Jagan Teki wrote: > > > > > > Add devm OF helper to return the next DSI bridge in the chain. > > > > > > > > > > > > Unlike general bridge return helper devm_drm_of_get_bridge, this > > > > > > helper uses the dsi specific panel_or_bridge helper to find the > > > > > > next DSI device in the pipeline. > > > > > > > > > > > > Helper lookup a given child DSI node or a DT node's port and > > > > > > endpoint number, find the connected node and return either > > > > > > the associated struct drm_panel or drm_bridge device. > > > > > > > > > > I'm not sure that using a device managed helper is the right choice > > > > > here. The bridge will stay longer than the backing device so it will > > > > > create a use-after-free. You should probably use a DRM-managed action > > > > > here instead. > > > > > > > > Thanks for the comments. If I understand correctly we can use > > > > drmm_panel_bridge_add instead devm_drm_panel_bridge_add once we found > > > > the panel or bridge - am I correct? > > > > > > It's not that we can, it's that the devm_panel_bridge_add is unsafe: > > > when the module is removed the device will go away and all the devm > > > resources freed, but the DRM device sticks around until the last > > > application with a fd open closes that fd. > > > > Would you please check this, Here I'm trying to do > > > > 1. find a panel or bridge > > 2. if panel add it as a panel bridge > > 3. add DRM-managed action with the help of bridge->dev after step 2. > > The logic is sound in your patch > > > Didn't test the behavior, just wanted to check whether it can be a > > possibility to use bridge->dev as this dev is assigned with > > encoder->dev during the bridge attach the chain. Please check and let > > me know. > > > > struct drm_bridge *devm_drm_of_dsi_get_bridge(struct device *dev, > > struct device_node *np, > > u32 port, u32 endpoint) > > { > > struct drm_bridge *bridge; > > struct drm_panel *panel; > > int ret; > > > > ret = drm_of_dsi_find_panel_or_bridge(np, port, endpoint, > > &panel, &bridge); > > if (ret) > > return ERR_PTR(ret); > > > > if (panel) > > bridge = devm_drm_panel_bridge_add(dev, panel); > > > > if (IS_ERR(bridge)) > > return bridge; > > > > ret = drmm_add_action_or_reset(bridge->dev, > > drmm_drm_panel_bridge_release, > > bridge); > > if (ret) > > return ERR_PTR(ret); > > > > return bridge; > > } > > It's the implementation that isn't. You cannot use a devm hook to > register a KMS structure, so it's not that you should add a > drmm_add_action call, it's that you shouldn't call > devm_drm_panel_bridge_add in the first place. I think it is because the remove action helper uses drm_panel_bridge_remove instead of devm hook. > > So either you use drm_panel_bridge_add and a custom drmm action, or you > add a drmm_panel_bridge_add function and use it. It is not possible to use this helper as it is expecting drm_device point that would get only if we found panel_bridge, so combined calls here can help. Would you please check this updated implementation and let me know? struct drm_bridge *drmm_panel_bridge_add_nodrm(struct drm_panel *panel) { struct drm_bridge *bridge; int ret; bridge = drm_panel_bridge_add_typed(panel, panel->connector_type); if (IS_ERR(bridge)) return bridge; ret = drmm_add_action_or_reset(bridge->dev, drmm_drm_panel_bridge_release, bridge); if (ret) return ERR_PTR(ret); bridge->pre_enable_prev_first = panel->prepare_prev_first; return bridge; } struct drm_bridge *drm_of_dsi_get_bridge(struct device_node *np, u32 port, u32 endpoint) { struct drm_bridge *bridge; struct drm_panel *panel; int ret; ret = drm_of_dsi_find_panel_or_bridge(np, port, endpoint, &panel, &bridge); if (ret) return ERR_PTR(ret); if (panel) bridge = drmm_panel_bridge_add_nodrm(panel); return bridge; } Thanks, Jagan.