diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c index 94fbc7cc5e19..1231905150d0 100644 --- a/drivers/gpu/drm/pl111/pl111_drv.c +++ b/drivers/gpu/drm/pl111/pl111_drv.c @@ -58,6 +58,8 @@ #include #include #include +#include +#include #include #include @@ -85,9 +87,13 @@ static int pl111_modeset_init(struct drm_device *dev) { struct drm_mode_config *mode_config; struct pl111_drm_dev_private *priv = dev->dev_private; - struct drm_panel *panel; - struct drm_bridge *bridge; + struct device_node *np = dev->dev->of_node; + struct device_node *remote; + struct drm_panel *panel = NULL; + struct drm_bridge *bridge = NULL; + bool defer = false; int ret = 0; + int i; drm_mode_config_init(dev); mode_config = &dev->mode_config; @@ -97,10 +103,54 @@ static int pl111_modeset_init(struct drm_device *dev) mode_config->min_height = 1; mode_config->max_height = 768; - ret = drm_of_find_panel_or_bridge(dev->dev->of_node, - 0, 0, &panel, &bridge); - if (ret && ret != -ENODEV) - return ret; + i = 0; + for_each_endpoint_of_node(np, remote) { + struct drm_panel *tmp_panel; + struct drm_bridge *tmp_bridge; + + dev_dbg(dev->dev, "checking endpoint %d\n", i); + + ret = drm_of_find_panel_or_bridge(dev->dev->of_node, + 0, i, + &tmp_panel, + &tmp_bridge); + if (ret) { + if (ret == -EPROBE_DEFER) { + /* + * Something deferred, but that is often just + * another way of saying -ENODEV, but let's + * cast a vote for later deferral. + */ + defer = true; + } else if (ret != -ENODEV) { + /* Continue, maybe something else is working */ + dev_err(dev->dev, + "endpoint %d returns %d\n", i, ret); + } + } + + if (tmp_panel) { + dev_info(dev->dev, + "found panel on endpoint %d\n", i); + panel = tmp_panel; + } + if (tmp_bridge) { + dev_info(dev->dev, + "found bridge on endpoint %d\n", i); + bridge = tmp_bridge; + } + + i++; + } + + /* + * If we can't find neither panel nor bridge on any of the + * endpoints, and any of them retured -EPROBE_DEFER, then + * let's defer this driver too. + */ + if ((!panel && !bridge) && defer) + return -EPROBE_DEFER; + if (panel) { bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_Unknown);