drm: of: Lookup if child node has panel or bridge
authorJagan Teki <jagan@amarulasolutions.com>
Wed, 2 Feb 2022 16:04:14 +0000 (21:34 +0530)
committerMaxime Ripard <maxime@cerno.tech>
Fri, 25 Feb 2022 16:08:37 +0000 (17:08 +0100)
Devices can also be child nodes when we also control that device
through the upstream device (ie, MIPI-DCS for a MIPI-DSI device).

drm_of_find_panel_or_bridge can lookup panel or bridge for a given
device has port and endpoint and it fails to lookup if the device
has a child nodes.

This patch add support to lookup for a child node of the given parent
that isn't either port or ports.

Example OF graph representation of DSI host, which has port but
not has ports and has child panel node.

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>;
};
};

Example OF graph representation of DSI host, which has ports but
not has port and has child panel node.

dsi {
        compatible = "samsung,exynos5433-mipi-dsi";
        #address-cells = <1>;
        #size-cells = <0>;

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

port@0 {
reg = <0>;

                 dsi_to_mic: endpoint {
                         remote-endpoint = <&mic_to_dsi>;
                 };
                };
        };

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

Example OF graph representation of DSI host, which has neither a port
nor a ports but has child panel node.

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

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

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202160414.16493-1-jagan@amarulasolutions.com
drivers/gpu/drm/drm_of.c

index 59d368e..9d90cd7 100644 (file)
@@ -249,6 +249,21 @@ int drm_of_find_panel_or_bridge(const struct device_node *np,
        if (panel)
                *panel = NULL;
 
+       /**
+        * Devices can also be child nodes when we also control that device
+        * through the upstream device (ie, MIPI-DCS for a MIPI-DSI device).
+        *
+        * Lookup for a child node of the given parent that isn't either port
+        * or ports.
+        */
+       for_each_available_child_of_node(np, remote) {
+               if (of_node_name_eq(remote, "port") ||
+                   of_node_name_eq(remote, "ports"))
+                       continue;
+
+               goto of_find_panel_or_bridge;
+       }
+
        /*
         * 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,
@@ -259,6 +274,8 @@ int drm_of_find_panel_or_bridge(const struct device_node *np,
                return -ENODEV;
 
        remote = of_graph_get_remote_node(np, port, endpoint);
+
+of_find_panel_or_bridge:
        if (!remote)
                return -ENODEV;