This driver looks up the next_bridge at probe time and stores it in hdmi->bridge.next_bridge, but only uses the stored value when attaching, and only in the DRM_BRIDGE_ATTACH_NO_CONNECTOR case.
This will be problematic with an upcoming change, adding an hdmi-connector using a device tree overlay when not present. That change is in turn necessary to migrate the i.MX LCDIF driver to the bridge-connector. The problem is that, adding the hdmi-connector via an overlay, devlink considers hdmi-connector a consumer of the dw-hdmi device, generating a chicken-egg problem: * hdmi-connector probe won't be tried until dw-hdmi is probed (devlink) * dw-hdmi probe will defer until it finds the next_bridge (the hdmi-connector wrapper bridge) In preparation for those changes, move the next_bridge lookup from probe to attach, when it is actually used. This allows dw-hdmi to probe, so that the hdmi-connector can probe as well. Also avoid storing the pointer in hdmi->bridge.next_bridge: the value is computed when needed, thus a local variable is enough. Finally, this also allows to slightly improve the code by not doing any DT lookup in the !DRM_BRIDGE_ATTACH_NO_CONNECTOR case. Signed-off-by: Luca Ceresoli <[email protected]> --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 41 +++++++++---------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index a668d66aeece..4ee865a1a6c8 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2914,9 +2914,18 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge, if (WARN_ON((flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) && !hdmi->plat_data->output_port)) return -EINVAL; - if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) - return drm_bridge_attach(encoder, hdmi->bridge.next_bridge, - bridge, flags); + if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { + struct device_node *remote __free(device_node) = + of_graph_get_remote_node(hdmi->dev->of_node, + hdmi->plat_data->output_port, -1); + if (!remote) + return -EPROBE_DEFER; + + struct drm_bridge *next_bridge __free(drm_bridge_put) = + of_drm_find_and_get_bridge(remote); + + return drm_bridge_attach(encoder, next_bridge, bridge, flags); + } return dw_hdmi_connector_create(hdmi); } @@ -3307,28 +3316,6 @@ static void dw_hdmi_init_hw(struct dw_hdmi *hdmi) * Probe/remove API, used from platforms based on the DRM bridge API. */ -static int dw_hdmi_parse_dt(struct dw_hdmi *hdmi) -{ - struct device_node *remote; - - if (!hdmi->plat_data->output_port) - return 0; - - - remote = of_graph_get_remote_node(hdmi->dev->of_node, - hdmi->plat_data->output_port, - -1); - if (!remote) - return -ENODEV; - - hdmi->bridge.next_bridge = of_drm_find_and_get_bridge(remote); - of_node_put(remote); - if (!hdmi->bridge.next_bridge) - return -EPROBE_DEFER; - - return 0; -} - bool dw_hdmi_bus_fmt_is_420(struct dw_hdmi *hdmi) { return hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format); @@ -3373,10 +3360,6 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, mutex_init(&hdmi->cec_notifier_mutex); spin_lock_init(&hdmi->audio_lock); - ret = dw_hdmi_parse_dt(hdmi); - if (ret < 0) - return ERR_PTR(ret); - ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); if (ddc_node) { hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node); -- 2.53.0
