linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/5] drm/rockchip: dw_hdmi: Call drm_encoder_cleanup() in error path
@ 2016-03-07 22:00 Douglas Anderson
  2016-03-07 22:00 ` [PATCH v2 3/5] drm/rockchip: vop: Fix vop crtc cleanup Douglas Anderson
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Douglas Anderson @ 2016-03-07 22:00 UTC (permalink / raw)
  To: linux-arm-kernel

The drm_encoder_cleanup() was missing both from the error path of
dw_hdmi_rockchip_bind().  This caused a crash when slub_debug was
enabled and we ended up deferring probe of HDMI at boot.

This call isn't needed from unbind() because if dw_hdmi_bind() returns
no error then it takes over the job of freeing the encoder (in
dw_hdmi_unbind).

Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
Changes in v2: None

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 3d3cf2f8891e..88776aba984e 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -293,7 +293,16 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 	drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs,
 			 DRM_MODE_ENCODER_TMDS, NULL);
 
-	return dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data);
+	ret = dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data);
+
+	/*
+	 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
+	 * which would have called the encoder cleanup.  Do it manually.
+	 */
+	if (ret)
+		drm_encoder_cleanup(encoder);
+
+	return ret;
 }
 
 static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 3/5] drm/rockchip: vop: Fix vop crtc cleanup
  2016-03-07 22:00 [PATCH v2 1/5] drm/rockchip: dw_hdmi: Call drm_encoder_cleanup() in error path Douglas Anderson
@ 2016-03-07 22:00 ` Douglas Anderson
  2016-03-07 22:00 ` [PATCH v2 4/5] drm/rockchip: dw_hdmi: Don't call platform_set_drvdata() Douglas Anderson
  2016-03-28  6:45 ` [PATCH v2 1/5] drm/rockchip: dw_hdmi: Call drm_encoder_cleanup() in error path Mark yao
  2 siblings, 0 replies; 4+ messages in thread
From: Douglas Anderson @ 2016-03-07 22:00 UTC (permalink / raw)
  To: linux-arm-kernel

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>
---
Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index fd370548d7d7..f86f797f10fd 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1108,7 +1108,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;
@@ -1148,7 +1148,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);
 
@@ -1181,6 +1181,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;
 	}
 
@@ -1194,7 +1195,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;
 }
@@ -1202,9 +1204,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);
 }
 
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 4/5] drm/rockchip: dw_hdmi: Don't call platform_set_drvdata()
  2016-03-07 22:00 [PATCH v2 1/5] drm/rockchip: dw_hdmi: Call drm_encoder_cleanup() in error path Douglas Anderson
  2016-03-07 22:00 ` [PATCH v2 3/5] drm/rockchip: vop: Fix vop crtc cleanup Douglas Anderson
@ 2016-03-07 22:00 ` Douglas Anderson
  2016-03-28  6:45 ` [PATCH v2 1/5] drm/rockchip: dw_hdmi: Call drm_encoder_cleanup() in error path Mark yao
  2 siblings, 0 replies; 4+ messages in thread
From: Douglas Anderson @ 2016-03-07 22:00 UTC (permalink / raw)
  To: linux-arm-kernel

The Rockchip dw_hdmi driver just called platform_set_drvdata() to get
your hopes up that maybe, somehow, you'd be able to retrieve the 'struct
rockchip_hdmi' from a pointer to the 'struct device'.  You can't.  When
we call dw_hdmi_bind() the main driver calls dev_set_drvdata(), which
clobbers our setting.

Let's just remove the platform_set_drvdata() to avoid dashing people's
hopes.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
Changes in v2:
- Don't call platform_set_drvdata() new for v2.

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 88776aba984e..d5cfef75fc80 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -271,8 +271,6 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 	if (!iores)
 		return -ENXIO;
 
-	platform_set_drvdata(pdev, hdmi);
-
 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
 	/*
 	 * If we failed to find the CRTC(s) which this encoder is
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 1/5] drm/rockchip: dw_hdmi: Call drm_encoder_cleanup() in error path
  2016-03-07 22:00 [PATCH v2 1/5] drm/rockchip: dw_hdmi: Call drm_encoder_cleanup() in error path Douglas Anderson
  2016-03-07 22:00 ` [PATCH v2 3/5] drm/rockchip: vop: Fix vop crtc cleanup Douglas Anderson
  2016-03-07 22:00 ` [PATCH v2 4/5] drm/rockchip: dw_hdmi: Don't call platform_set_drvdata() Douglas Anderson
@ 2016-03-28  6:45 ` Mark yao
  2 siblings, 0 replies; 4+ messages in thread
From: Mark yao @ 2016-03-28  6:45 UTC (permalink / raw)
  To: linux-arm-kernel

On 2016?03?08? 06:00, Douglas Anderson wrote:
> The drm_encoder_cleanup() was missing both from the error path of
> dw_hdmi_rockchip_bind().  This caused a crash when slub_debug was
> enabled and we ended up deferring probe of HDMI at boot.
>
> This call isn't needed from unbind() because if dw_hdmi_bind() returns
> no error then it takes over the job of freeing the encoder (in
> dw_hdmi_unbind).
>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>

Hi Douglas

it seems has no doubt on these patch, and it works on my board, So I'd 
like to apply following three patches.

[PATCH v2 1/5] drm/rockchip: dw_hdmi: Call drm_encoder_cleanup() in 
error path
[PATCH v2 3/5] drm/rockchip: vop: Fix vop crtc cleanup
[PATCH v2 4/5] drm/rockchip: dw_hdmi: Don't call platform_set_drvdata()

Thanks for your fixes.

-- ?ark Yao

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-03-28  6:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-07 22:00 [PATCH v2 1/5] drm/rockchip: dw_hdmi: Call drm_encoder_cleanup() in error path Douglas Anderson
2016-03-07 22:00 ` [PATCH v2 3/5] drm/rockchip: vop: Fix vop crtc cleanup Douglas Anderson
2016-03-07 22:00 ` [PATCH v2 4/5] drm/rockchip: dw_hdmi: Don't call platform_set_drvdata() Douglas Anderson
2016-03-28  6:45 ` [PATCH v2 1/5] drm/rockchip: dw_hdmi: Call drm_encoder_cleanup() in error path Mark yao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).