Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 328b51c0 authored by Douglas Anderson's avatar Douglas Anderson Committed by Mark Yao
Browse files

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: default avatarDouglas Anderson <dianders@chromium.org>
parent 948cf427
Loading
Loading
Loading
Loading
+24 −3
Original line number Diff line number Diff line
@@ -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 @@ static int vop_create_crtc(struct vop *vop)
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);
}