diff options
Diffstat (limited to 'drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c')
| -rw-r--r-- | drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c | 66 |
1 files changed, 29 insertions, 37 deletions
diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c index 82a2bba375ad..9dc2b3d2ecef 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c @@ -35,7 +35,6 @@ struct imx8qxp_pxl2dpi { struct regmap *regmap; struct drm_bridge bridge; - struct drm_bridge *next_bridge; struct drm_bridge *companion; struct device *dev; struct imx_sc_ipc *ipc_handle; @@ -60,10 +59,20 @@ static int imx8qxp_pxl2dpi_bridge_attach(struct drm_bridge *bridge, } return drm_bridge_attach(encoder, - p2d->next_bridge, bridge, + p2d->bridge.next_bridge, bridge, DRM_BRIDGE_ATTACH_NO_CONNECTOR); } +static void imx8qxp_pxl2dpi_bridge_destroy(struct drm_bridge *bridge) +{ + struct imx8qxp_pxl2dpi *p2d = bridge->driver_private; + + if (!p2d) + return; + + drm_bridge_put(p2d->companion); +} + static int imx8qxp_pxl2dpi_bridge_atomic_check(struct drm_bridge *bridge, struct drm_bridge_state *bridge_state, @@ -203,6 +212,7 @@ static const struct drm_bridge_funcs imx8qxp_pxl2dpi_bridge_funcs = { .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .atomic_reset = drm_atomic_helper_bridge_reset, .attach = imx8qxp_pxl2dpi_bridge_attach, + .destroy = imx8qxp_pxl2dpi_bridge_destroy, .atomic_check = imx8qxp_pxl2dpi_bridge_atomic_check, .mode_set = imx8qxp_pxl2dpi_bridge_mode_set, .atomic_disable = imx8qxp_pxl2dpi_bridge_atomic_disable, @@ -252,40 +262,27 @@ out: return ep; } -static struct drm_bridge * -imx8qxp_pxl2dpi_find_next_bridge(struct imx8qxp_pxl2dpi *p2d) +static int imx8qxp_pxl2dpi_find_next_bridge(struct imx8qxp_pxl2dpi *p2d) { - struct device_node *ep, *remote; - struct drm_bridge *next_bridge; - int ret; - - ep = imx8qxp_pxl2dpi_get_available_ep_from_port(p2d, 1); - if (IS_ERR(ep)) { - ret = PTR_ERR(ep); - return ERR_PTR(ret); - } + struct device_node *ep __free(device_node) = + imx8qxp_pxl2dpi_get_available_ep_from_port(p2d, 1); + if (IS_ERR(ep)) + return PTR_ERR(ep); - remote = of_graph_get_remote_port_parent(ep); + struct device_node *remote __free(device_node) = of_graph_get_remote_port_parent(ep); if (!remote || !of_device_is_available(remote)) { DRM_DEV_ERROR(p2d->dev, "no available remote\n"); - next_bridge = ERR_PTR(-ENODEV); - goto out; + return -ENODEV; } else if (!of_device_is_available(remote->parent)) { DRM_DEV_ERROR(p2d->dev, "remote parent is not available\n"); - next_bridge = ERR_PTR(-ENODEV); - goto out; + return -ENODEV; } - next_bridge = of_drm_find_bridge(remote); - if (!next_bridge) { - next_bridge = ERR_PTR(-EPROBE_DEFER); - goto out; - } -out: - of_node_put(remote); - of_node_put(ep); + p2d->bridge.next_bridge = of_drm_find_and_get_bridge(remote); + if (!p2d->bridge.next_bridge) + return -EPROBE_DEFER; - return next_bridge; + return 0; } static int imx8qxp_pxl2dpi_set_pixel_link_sel(struct imx8qxp_pxl2dpi *p2d) @@ -344,7 +341,7 @@ static int imx8qxp_pxl2dpi_parse_dt_companion(struct imx8qxp_pxl2dpi *p2d) goto out; } - p2d->companion = of_drm_find_bridge(companion); + p2d->companion = of_drm_find_and_get_bridge(companion); if (!p2d->companion) { ret = -EPROBE_DEFER; DRM_DEV_DEBUG_DRIVER(p2d->dev, @@ -361,8 +358,8 @@ static int imx8qxp_pxl2dpi_parse_dt_companion(struct imx8qxp_pxl2dpi *p2d) * the next bridges are connected to. If they are marked as expecting * even pixels and odd pixels than we need to use the companion PXL2DPI. */ - port1 = of_graph_get_port_by_id(p2d->next_bridge->of_node, 1); - port2 = of_graph_get_port_by_id(companion_p2d->next_bridge->of_node, 1); + port1 = of_graph_get_port_by_id(p2d->bridge.next_bridge->of_node, 1); + port2 = of_graph_get_port_by_id(companion_p2d->bridge.next_bridge->of_node, 1); dual_link = drm_of_lvds_get_dual_link_pixel_order(port1, port2); of_node_put(port1); of_node_put(port2); @@ -418,14 +415,9 @@ static int imx8qxp_pxl2dpi_bridge_probe(struct platform_device *pdev) return ret; } - p2d->next_bridge = imx8qxp_pxl2dpi_find_next_bridge(p2d); - if (IS_ERR(p2d->next_bridge)) { - ret = PTR_ERR(p2d->next_bridge); - if (ret != -EPROBE_DEFER) - DRM_DEV_ERROR(dev, "failed to find next bridge: %d\n", - ret); + ret = imx8qxp_pxl2dpi_find_next_bridge(p2d); + if (ret) return ret; - } ret = imx8qxp_pxl2dpi_set_pixel_link_sel(p2d); if (ret) |
