diff options
author | Javier Martinez Canillas <javier@osg.samsung.com> | 2016-01-29 10:09:31 -0500 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2016-02-01 00:54:29 -0500 |
commit | 37e110625eeeaba83e8cb763ab7645f0678c6f8e (patch) | |
tree | 2db5f84a05dcb5edc0e3087eff6968db281426c9 | |
parent | 010848a73fd87a481f263f7322e733f129ac398b (diff) |
drm/exynos: dp: Fix panel and bridge lookup logic
Commit a9fa852886fd ("drm/exynos: dp: add of_graph dt binding support
for panel") made the Exynos DP DT binding more consistent since the OF
graph could be used to lookup either a panel or a bridge device node.
Before that commit, a panel would be looked up using a phandle and a
bridge using the OF graph which made the DT binding not consistent.
But the patch broke the later case since not finding a panel dev node
would cause the driver's to do a probe deferral instead of attempting
to lookup a bridge device node associated with the remote endpoint.
So instead of returning a -EPROBE_DEFER if a panel is not found, check
if there's a bridge and only do a probe deferral if both aren't found.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
Tested-by: Michal Suchanek <hramrach@gmail.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_dp_core.c | 55 |
1 files changed, 25 insertions, 30 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c index b79c316c2ad2..673164b331c8 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c | |||
@@ -1392,7 +1392,7 @@ static const struct component_ops exynos_dp_ops = { | |||
1392 | static int exynos_dp_probe(struct platform_device *pdev) | 1392 | static int exynos_dp_probe(struct platform_device *pdev) |
1393 | { | 1393 | { |
1394 | struct device *dev = &pdev->dev; | 1394 | struct device *dev = &pdev->dev; |
1395 | struct device_node *panel_node = NULL, *bridge_node, *endpoint = NULL; | 1395 | struct device_node *np = NULL, *endpoint = NULL; |
1396 | struct exynos_dp_device *dp; | 1396 | struct exynos_dp_device *dp; |
1397 | int ret; | 1397 | int ret; |
1398 | 1398 | ||
@@ -1404,41 +1404,36 @@ static int exynos_dp_probe(struct platform_device *pdev) | |||
1404 | platform_set_drvdata(pdev, dp); | 1404 | platform_set_drvdata(pdev, dp); |
1405 | 1405 | ||
1406 | /* This is for the backward compatibility. */ | 1406 | /* This is for the backward compatibility. */ |
1407 | panel_node = of_parse_phandle(dev->of_node, "panel", 0); | 1407 | np = of_parse_phandle(dev->of_node, "panel", 0); |
1408 | if (panel_node) { | 1408 | if (np) { |
1409 | dp->panel = of_drm_find_panel(panel_node); | 1409 | dp->panel = of_drm_find_panel(np); |
1410 | of_node_put(panel_node); | 1410 | of_node_put(np); |
1411 | if (!dp->panel) | 1411 | if (!dp->panel) |
1412 | return -EPROBE_DEFER; | 1412 | return -EPROBE_DEFER; |
1413 | } else { | ||
1414 | endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); | ||
1415 | if (endpoint) { | ||
1416 | panel_node = of_graph_get_remote_port_parent(endpoint); | ||
1417 | if (panel_node) { | ||
1418 | dp->panel = of_drm_find_panel(panel_node); | ||
1419 | of_node_put(panel_node); | ||
1420 | if (!dp->panel) | ||
1421 | return -EPROBE_DEFER; | ||
1422 | } else { | ||
1423 | DRM_ERROR("no port node for panel device.\n"); | ||
1424 | return -EINVAL; | ||
1425 | } | ||
1426 | } | ||
1427 | } | ||
1428 | |||
1429 | if (endpoint) | ||
1430 | goto out; | 1413 | goto out; |
1414 | } | ||
1431 | 1415 | ||
1432 | endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); | 1416 | endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); |
1433 | if (endpoint) { | 1417 | if (endpoint) { |
1434 | bridge_node = of_graph_get_remote_port_parent(endpoint); | 1418 | np = of_graph_get_remote_port_parent(endpoint); |
1435 | if (bridge_node) { | 1419 | if (np) { |
1436 | dp->ptn_bridge = of_drm_find_bridge(bridge_node); | 1420 | /* The remote port can be either a panel or a bridge */ |
1437 | of_node_put(bridge_node); | 1421 | dp->panel = of_drm_find_panel(np); |
1438 | if (!dp->ptn_bridge) | 1422 | if (!dp->panel) { |
1439 | return -EPROBE_DEFER; | 1423 | dp->ptn_bridge = of_drm_find_bridge(np); |
1440 | } else | 1424 | if (!dp->ptn_bridge) { |
1441 | return -EPROBE_DEFER; | 1425 | of_node_put(np); |
1426 | return -EPROBE_DEFER; | ||
1427 | } | ||
1428 | } | ||
1429 | of_node_put(np); | ||
1430 | } else { | ||
1431 | DRM_ERROR("no remote endpoint device node found.\n"); | ||
1432 | return -EINVAL; | ||
1433 | } | ||
1434 | } else { | ||
1435 | DRM_ERROR("no port endpoint subnode found.\n"); | ||
1436 | return -EINVAL; | ||
1442 | } | 1437 | } |
1443 | 1438 | ||
1444 | out: | 1439 | out: |