#include <linux/dma-buf.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
 
 #include <drm/drmP.h>
 #include <drm/drm_atomic_helper.h>
 {
        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;
        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);