/* * of_coresight_parse_endpoint : Parse the given output endpoint @ep * and fill the connection information in @conn * * Parses the local port, remote device name and the remote port. * * Returns : * 1 - If the parsing is successful and a connection record * was created for an output connection. * 0 - If the parsing completed without any fatal errors. * -Errno - Fatal error, abort the scanning. */ static int of_coresight_parse_endpoint(struct device *dev, struct device_node *ep, struct coresight_connection *conn) { int ret = 0; struct of_endpoint endpoint, rendpoint; struct device_node *rparent = NULL; struct device_node *rep = NULL; struct device *rdev = NULL; do { /* Parse the local port details */ if (of_graph_parse_endpoint(ep, &endpoint)) break; /* * Get a handle on the remote endpoint and the device it is * attached to. */ rep = of_graph_get_remote_endpoint(ep); if (!rep) break; rparent = of_coresight_get_port_parent(rep); if (!rparent) break; if (of_graph_parse_endpoint(rep, &rendpoint)) break; /* If the remote device is not available, defer probing */ rdev = of_coresight_get_endpoint_device(rparent); if (!rdev) { ret = -EPROBE_DEFER; break; } conn->outport = endpoint.port; conn->child_name = devm_kstrdup(dev, dev_name(rdev), GFP_KERNEL); conn->child_port = rendpoint.port; /* Connection record updated */ ret = 1; } while (0); of_node_put(rparent); of_node_put(rep); put_device(rdev); return ret; }
int fsl_dcu_create_outputs(struct fsl_dcu_drm_device *fsl_dev) { struct of_endpoint ep; struct device_node *ep_node, *panel_node; int ret; /* This is for backward compatibility */ panel_node = of_parse_phandle(fsl_dev->np, "fsl,panel", 0); if (panel_node) { fsl_dev->connector.panel = of_drm_find_panel(panel_node); of_node_put(panel_node); if (!fsl_dev->connector.panel) return -EPROBE_DEFER; return fsl_dcu_attach_panel(fsl_dev, fsl_dev->connector.panel); } ep_node = of_graph_get_next_endpoint(fsl_dev->np, NULL); if (!ep_node) return -ENODEV; ret = of_graph_parse_endpoint(ep_node, &ep); of_node_put(ep_node); if (ret) return -ENODEV; return fsl_dcu_attach_endpoint(fsl_dev, &ep); }
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); }
struct coresight_platform_data *of_get_coresight_platform_data( struct device *dev, struct device_node *node) { int i = 0, ret = 0, cpu; struct coresight_platform_data *pdata; struct of_endpoint endpoint, rendpoint; struct device *rdev; struct device_node *dn; struct device_node *ep = NULL; struct device_node *rparent = NULL; struct device_node *rport = NULL; pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return ERR_PTR(-ENOMEM); /* Use device name as sysfs handle */ pdata->name = dev_name(dev); /* Get the number of input and output port for this component */ of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport); if (pdata->nr_outport) { ret = of_coresight_alloc_memory(dev, pdata); if (ret) return ERR_PTR(ret); /* Iterate through each port to discover topology */ do { /* Get a handle on a port */ ep = of_graph_get_next_endpoint(node, ep); if (!ep) break; /* * No need to deal with input ports, processing for as * processing for output ports will deal with them. */ if (of_find_property(ep, "slave-mode", NULL)) continue; /* Get a handle on the local endpoint */ ret = of_graph_parse_endpoint(ep, &endpoint); if (ret) continue; /* The local out port number */ pdata->outports[i] = endpoint.id; /* * Get a handle on the remote port and parent * attached to it. */ rparent = of_graph_get_remote_port_parent(ep); rport = of_graph_get_remote_port(ep); if (!rparent || !rport) continue; if (of_graph_parse_endpoint(rport, &rendpoint)) continue; rdev = of_coresight_get_endpoint_device(rparent); if (!rdev) continue; pdata->child_names[i] = dev_name(rdev); pdata->child_ports[i] = rendpoint.id; i++; } while (ep); } /* Affinity defaults to CPU0 */ pdata->cpu = 0; dn = of_parse_phandle(node, "cpu", 0); for (cpu = 0; dn && cpu < nr_cpu_ids; cpu++) { if (dn == of_get_cpu_node(cpu, NULL)) { pdata->cpu = cpu; break; } } return pdata; }