[2/2] drm: of: Lookup if child node is panel or bridge

Message ID 20211207054747.461029-3-jagan@amarulasolutions.com
State New
Headers show
Series
  • drm: of: Lookup child panel_or_bridge
Related show

Commit Message

Jagan Teki Dec. 7, 2021, 5:47 a.m. UTC
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 <jagan@amarulasolutions.com>
---
 drivers/gpu/drm/drm_of.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

Patch

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