drm_of_find_panel_or_bridge can lookup panel or bridge for
a given node based on the OF graph port and endpoint and it
fails to use if the given node has a child panel or bridge.

This patch add support to lookup that given node has child
panel or bridge however that child node cannot be a 'port'.

Examples OF graph representation of DSI host, which doesn't
have 'ports'

dsi {
        compatible = "allwinner,sun6i-a31-mipi-dsi";
        #address-cells = <1>;
        #size-cells = <0>;

        port {
                dsi_in_tcon0: endpoint {
                        remote-endpoint = <tcon0_out_dsi>;
        };

        panel@0 {
                reg = <0>;
        };
};

dsi {
        compatible = "allwinner,sun6i-a31-mipi-dsi";
        #address-cells = <1>;
        #size-cells = <0>;

        port {
                dsi_in_tcon0: endpoint {
                        remote-endpoint = <tcon0_out_dsi>;
        };

        bridge@0 {
                reg = <0>;

                ports {
                        #address-cells = <1>;
                        #size-cells = <0>;

                        bridge_out: port@1 {
                                reg = <1>;

                                bridge_out_panel: endpoint {
                                        remote-endpoint = <&panel_out_bridge>;
                                };
                        };
                };
        };
};

dsi0 {
        compatible = "ste,mcde-dsi";
        #address-cells = <1>;
        #size-cells = <0>;

        panel@0 {
                reg = <0>;
        };
};

Signed-off-by: Jagan Teki <ja...@amarulasolutions.com>
---
 drivers/gpu/drm/drm_of.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 59d368ea006b..1c4cb809d7bc 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -249,18 +249,34 @@ int drm_of_find_panel_or_bridge(const struct device_node 
*np,
        if (panel)
                *panel = NULL;
 
-       /*
-        * of_graph_get_remote_node() produces a noisy error message if port
-        * node isn't found and the absence of the port is a legit case here,
-        * so at first we silently check whether graph presents in the
-        * device-tree node.
+       /**
+        * Some OF graphs don't require 'ports' to represent the next output
+        * instead, it simply adds a child node on a given parent node.
+        * Lookup that child node for a given parent however that child
+        * cannot be a 'port'.
+        *
+        * Add precedence to lookup non port child as of_graph_get_remote_node()
+        * returns valid even if OF graph has 'port' but that OF graph remote
+        * node is not register panel or bridge.
         */
-       if (!of_graph_is_present(np))
-               return -ENODEV;
+       if (!of_get_child_by_name(np, "ports")) {
+               remote = of_get_non_port_child(np);
+               if (!remote)
+                       return -ENODEV;
+       } else {
+               /*
+                * of_graph_get_remote_node() produces a noisy error message if 
port
+                * node isn't found and the absence of the port is a legit case 
here,
+                * so at first we silently check whether graph presents in the
+                * device-tree node.
+                */
+               if (!of_graph_is_present(np))
+                       return -ENODEV;
 
-       remote = of_graph_get_remote_node(np, port, endpoint);
-       if (!remote)
-               return -ENODEV;
+               remote = of_graph_get_remote_node(np, port, endpoint);
+               if (!remote)
+                       return -ENODEV;
+       }
 
        if (panel) {
                *panel = of_drm_find_panel(remote);
-- 
2.25.1

Reply via email to