static int exynos_dp_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = NULL, *endpoint = NULL; struct exynos_dp_device *dp; dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device), GFP_KERNEL); if (!dp) return -ENOMEM; /* * We just use the drvdata until driver run into component * add function, and then we would set drvdata to null, so * that analogix dp driver would take charge of the drvdata. */ platform_set_drvdata(pdev, dp); /* This is for the backward compatibility. */ np = of_parse_phandle(dev->of_node, "panel", 0); if (np) { dp->plat_data.panel = of_drm_find_panel(np); of_node_put(np); if (!dp->plat_data.panel) return -EPROBE_DEFER; goto out; } endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); if (endpoint) { np = of_graph_get_remote_port_parent(endpoint); if (np) { /* The remote port can be either a panel or a bridge */ dp->plat_data.panel = of_drm_find_panel(np); if (!dp->plat_data.panel) { dp->ptn_bridge = of_drm_find_bridge(np); if (!dp->ptn_bridge) { of_node_put(np); return -EPROBE_DEFER; } } of_node_put(np); } else { DRM_ERROR("no remote endpoint device node found.\n"); return -EINVAL; } } else { DRM_ERROR("no port endpoint subnode found.\n"); return -EINVAL; } out: return component_add(&pdev->dev, &exynos_dp_ops); }
static int exynos_dp_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *panel_node, *bridge_node, *endpoint; struct exynos_dp_device *dp; int ret; dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device), GFP_KERNEL); if (!dp) return -ENOMEM; dp->display.type = EXYNOS_DISPLAY_TYPE_LCD; dp->display.ops = &exynos_dp_display_ops; platform_set_drvdata(pdev, dp); ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR, dp->display.type); if (ret) return ret; panel_node = of_parse_phandle(dev->of_node, "panel", 0); if (panel_node) { dp->panel = of_drm_find_panel(panel_node); of_node_put(panel_node); if (!dp->panel) return -EPROBE_DEFER; } endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); if (endpoint) { bridge_node = of_graph_get_remote_port_parent(endpoint); if (bridge_node) { dp->bridge = of_drm_find_bridge(bridge_node); of_node_put(bridge_node); if (!dp->bridge) return -EPROBE_DEFER; } else return -EPROBE_DEFER; } ret = component_add(&pdev->dev, &exynos_dp_ops); if (ret) exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR); return ret; }
int rcar_du_hdmienc_init(struct rcar_du_device *rcdu, struct rcar_du_encoder *renc, struct device_node *np) { struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc); struct drm_bridge *bridge; struct rcar_du_hdmienc *hdmienc; int ret; hdmienc = devm_kzalloc(rcdu->dev, sizeof(*hdmienc), GFP_KERNEL); if (hdmienc == NULL) return -ENOMEM; /* Locate the DRM bridge from the HDMI encoder DT node. */ bridge = of_drm_find_bridge(np); if (!bridge) return -EPROBE_DEFER; ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); if (ret < 0) return ret; drm_encoder_helper_add(encoder, &encoder_helper_funcs); renc->hdmi = hdmienc; hdmienc->renc = renc; /* Link the bridge to the encoder. */ bridge->encoder = encoder; encoder->bridge = bridge; ret = drm_bridge_attach(rcdu->ddev, bridge); if (ret) { drm_encoder_cleanup(encoder); return ret; } return 0; }
int tilcdc_attach_external_device(struct drm_device *ddev) { struct tilcdc_drm_private *priv = ddev->dev_private; struct device_node *remote_node; struct drm_bridge *bridge; int ret; remote_node = tilcdc_get_remote_node(ddev->dev->of_node); if (!remote_node) return 0; bridge = of_drm_find_bridge(remote_node); of_node_put(remote_node); if (!bridge) return -EPROBE_DEFER; priv->external_encoder = devm_kzalloc(ddev->dev, sizeof(*priv->external_encoder), GFP_KERNEL); if (!priv->external_encoder) return -ENOMEM; ret = drm_encoder_init(ddev, priv->external_encoder, &tilcdc_external_encoder_funcs, DRM_MODE_ENCODER_NONE, NULL); if (ret) { dev_err(ddev->dev, "drm_encoder_init() failed %d\n", ret); return ret; } ret = tilcdc_attach_bridge(ddev, bridge); if (ret) drm_encoder_cleanup(priv->external_encoder); return ret; }
static int fsl_dcu_attach_endpoint(struct fsl_dcu_drm_device *fsl_dev, const struct of_endpoint *ep) { struct drm_bridge *bridge; struct device_node *np; np = of_graph_get_remote_port_parent(ep->local_node); fsl_dev->connector.panel = of_drm_find_panel(np); if (fsl_dev->connector.panel) { of_node_put(np); return fsl_dcu_attach_panel(fsl_dev, fsl_dev->connector.panel); } bridge = of_drm_find_bridge(np); of_node_put(np); if (!bridge) return -ENODEV; fsl_dev->encoder.bridge = bridge; bridge->encoder = &fsl_dev->encoder; return drm_bridge_attach(fsl_dev->drm, bridge); }
static int rcar_lvds_parse_dt(struct rcar_lvds *lvds) { struct device_node *local_output = NULL; struct device_node *remote_input = NULL; struct device_node *remote = NULL; struct device_node *node; bool is_bridge = false; int ret = 0; local_output = of_graph_get_endpoint_by_regs(lvds->dev->of_node, 1, 0); if (!local_output) { dev_dbg(lvds->dev, "unconnected port@1\n"); return -ENODEV; } /* * Locate the connected entity and infer its type from the number of * endpoints. */ remote = of_graph_get_remote_port_parent(local_output); if (!remote) { dev_dbg(lvds->dev, "unconnected endpoint %pOF\n", local_output); ret = -ENODEV; goto done; } if (!of_device_is_available(remote)) { dev_dbg(lvds->dev, "connected entity %pOF is disabled\n", remote); ret = -ENODEV; goto done; } remote_input = of_graph_get_remote_endpoint(local_output); for_each_endpoint_of_node(remote, node) { if (node != remote_input) { /* * We've found one endpoint other than the input, this * must be a bridge. */ is_bridge = true; of_node_put(node); break; } } if (is_bridge) { lvds->next_bridge = of_drm_find_bridge(remote); if (!lvds->next_bridge) ret = -EPROBE_DEFER; } else { lvds->panel = of_drm_find_panel(remote); if (!lvds->panel) ret = -EPROBE_DEFER; } done: of_node_put(local_output); of_node_put(remote_input); of_node_put(remote); return ret; }
static int exynos_dp_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = NULL, *endpoint = NULL; struct exynos_dp_device *dp; int ret; dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device), GFP_KERNEL); if (!dp) return -ENOMEM; platform_set_drvdata(pdev, dp); /* This is for the backward compatibility. */ np = of_parse_phandle(dev->of_node, "panel", 0); if (np) { dp->panel = of_drm_find_panel(np); of_node_put(np); if (!dp->panel) return -EPROBE_DEFER; goto out; } endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); if (endpoint) { np = of_graph_get_remote_port_parent(endpoint); if (np) { /* The remote port can be either a panel or a bridge */ dp->panel = of_drm_find_panel(np); if (!dp->panel) { dp->ptn_bridge = of_drm_find_bridge(np); if (!dp->ptn_bridge) { of_node_put(np); return -EPROBE_DEFER; } } of_node_put(np); } else { DRM_ERROR("no remote endpoint device node found.\n"); return -EINVAL; } } else { DRM_ERROR("no port endpoint subnode found.\n"); return -EINVAL; } out: pm_runtime_enable(dev); ret = component_add(&pdev->dev, &exynos_dp_ops); if (ret) goto err_disable_pm_runtime; return ret; err_disable_pm_runtime: pm_runtime_disable(dev); return ret; }