mirror of
https://github.com/torvalds/linux.git
synced 2024-11-28 07:01:32 +00:00
drm/rockchip: vop: Fix vop crtc cleanup
This fixes a few problems in the vop crtc cleanup (handling error paths and cleanup upon exit): * The vop_create_crtc() error path had an unsafe version of the iterator used for iterating over all planes (though it was destroying planes in the iterator so should have used the safe version) * vop_destroy_crtc() - wasn't calling vop_plane_destroy(), which made slub_debug unhappy, at least if we ended up running this due to a deferred probe. * In vop_create_crtc() if we were missing the "port" device tree node we would fail but not return an error (found by code inspection). Fix these problems. Signed-off-by: Douglas Anderson <dianders@chromium.org>
This commit is contained in:
parent
948cf42700
commit
328b51c0f5
@ -1142,7 +1142,7 @@ static int vop_create_crtc(struct vop *vop)
|
||||
const struct vop_data *vop_data = vop->data;
|
||||
struct device *dev = vop->dev;
|
||||
struct drm_device *drm_dev = vop->drm_dev;
|
||||
struct drm_plane *primary = NULL, *cursor = NULL, *plane;
|
||||
struct drm_plane *primary = NULL, *cursor = NULL, *plane, *tmp;
|
||||
struct drm_crtc *crtc = &vop->crtc;
|
||||
struct device_node *port;
|
||||
int ret;
|
||||
@ -1182,7 +1182,7 @@ static int vop_create_crtc(struct vop *vop)
|
||||
ret = drm_crtc_init_with_planes(drm_dev, crtc, primary, cursor,
|
||||
&vop_crtc_funcs, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_cleanup_planes;
|
||||
|
||||
drm_crtc_helper_add(crtc, &vop_crtc_helper_funcs);
|
||||
|
||||
@ -1215,6 +1215,7 @@ static int vop_create_crtc(struct vop *vop)
|
||||
if (!port) {
|
||||
DRM_ERROR("no port node found in %s\n",
|
||||
dev->of_node->full_name);
|
||||
ret = -ENOENT;
|
||||
goto err_cleanup_crtc;
|
||||
}
|
||||
|
||||
@ -1228,7 +1229,8 @@ static int vop_create_crtc(struct vop *vop)
|
||||
err_cleanup_crtc:
|
||||
drm_crtc_cleanup(crtc);
|
||||
err_cleanup_planes:
|
||||
list_for_each_entry(plane, &drm_dev->mode_config.plane_list, head)
|
||||
list_for_each_entry_safe(plane, tmp, &drm_dev->mode_config.plane_list,
|
||||
head)
|
||||
drm_plane_cleanup(plane);
|
||||
return ret;
|
||||
}
|
||||
@ -1236,9 +1238,28 @@ err_cleanup_planes:
|
||||
static void vop_destroy_crtc(struct vop *vop)
|
||||
{
|
||||
struct drm_crtc *crtc = &vop->crtc;
|
||||
struct drm_device *drm_dev = vop->drm_dev;
|
||||
struct drm_plane *plane, *tmp;
|
||||
|
||||
rockchip_unregister_crtc_funcs(crtc);
|
||||
of_node_put(crtc->port);
|
||||
|
||||
/*
|
||||
* We need to cleanup the planes now. Why?
|
||||
*
|
||||
* The planes are "&vop->win[i].base". That means the memory is
|
||||
* all part of the big "struct vop" chunk of memory. That memory
|
||||
* was devm allocated and associated with this component. We need to
|
||||
* free it ourselves before vop_unbind() finishes.
|
||||
*/
|
||||
list_for_each_entry_safe(plane, tmp, &drm_dev->mode_config.plane_list,
|
||||
head)
|
||||
vop_plane_destroy(plane);
|
||||
|
||||
/*
|
||||
* Destroy CRTC after vop_plane_destroy() since vop_disable_plane()
|
||||
* references the CRTC.
|
||||
*/
|
||||
drm_crtc_cleanup(crtc);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user