static void sun4i_drv_traverse_endpoints(struct endpoint_list *list, struct device_node *node, int port_id) { struct device_node *ep, *remote, *port; port = of_graph_get_port_by_id(node, port_id); if (!port) { DRM_DEBUG_DRIVER("No output to bind on port %d\n", port_id); return; } for_each_available_child_of_node(port, ep) { remote = of_graph_get_remote_port_parent(ep); if (!remote) { DRM_DEBUG_DRIVER("Error retrieving the output node\n"); continue; } if (sun4i_drv_node_is_tcon(node)) { /* * TCON TOP is always probed before TCON. However, TCON * points back to TCON TOP when it is source for HDMI. * We have to skip it here to prevent infinite looping * between TCON TOP and TCON. */ if (sun4i_drv_node_is_tcon_top(remote)) { DRM_DEBUG_DRIVER("TCON output endpoint is TCON TOP... skipping\n"); of_node_put(remote); continue; } /* * If the node is our TCON with channel 0, the first * port is used for panel or bridges, and will not be * part of the component framework. */ if (sun4i_drv_node_is_tcon_with_ch0(node)) { struct of_endpoint endpoint; if (of_graph_parse_endpoint(ep, &endpoint)) { DRM_DEBUG_DRIVER("Couldn't parse endpoint\n"); of_node_put(remote); continue; } if (!endpoint.id) { DRM_DEBUG_DRIVER("Endpoint is our panel... skipping\n"); of_node_put(remote); continue; } } } kfifo_put(&list->fifo, remote); }
static int sun4i_drv_add_endpoints(struct device *dev, struct component_match **match, struct device_node *node) { struct device_node *port, *ep, *remote; int count = 0; /* * We don't support the frontend for now, so we will never * have a device bound. Just skip over it, but we still want * the rest our pipeline to be added. */ if (!sun4i_drv_node_is_frontend(node) && !of_device_is_available(node)) return 0; if (!sun4i_drv_node_is_frontend(node)) { /* Add current component */ DRM_DEBUG_DRIVER("Adding component %s\n", of_node_full_name(node)); drm_of_component_match_add(dev, match, compare_of, node); count++; } /* Inputs are listed first, then outputs */ port = of_graph_get_port_by_id(node, 1); if (!port) { DRM_DEBUG_DRIVER("No output to bind\n"); return count; } for_each_available_child_of_node(port, ep) { remote = of_graph_get_remote_port_parent(ep); if (!remote) { DRM_DEBUG_DRIVER("Error retrieving the output node\n"); of_node_put(remote); continue; } /* * If the node is our TCON, the first port is used for * panel or bridges, and will not be part of the * component framework. */ if (sun4i_drv_node_is_tcon(node)) { struct of_endpoint endpoint; if (of_graph_parse_endpoint(ep, &endpoint)) { DRM_DEBUG_DRIVER("Couldn't parse endpoint\n"); continue; } if (!endpoint.id) { DRM_DEBUG_DRIVER("Endpoint is our panel... skipping\n"); continue; } } /* Walk down our tree */ count += sun4i_drv_add_endpoints(dev, match, remote); of_node_put(remote); }