dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled
@ 2016-06-17 10:13 Lucas Stach
  2016-06-17 10:13 ` [PATCH 2/5] drm/imx: imx-ldb: check return code on panel attach Lucas Stach
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Lucas Stach @ 2016-06-17 10:13 UTC (permalink / raw)
  To: Philipp Zabel; +Cc: kernel, dri-devel, patchwork-lst

If there is no framebuffer mode that can be restored, all outputs should
be disabled in order to avoid information leaks.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/gpu/drm/imx/imx-drm-core.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index 82656654fb21..c63378661e11 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -63,7 +63,19 @@ static void imx_drm_driver_lastclose(struct drm_device *drm)
 {
 	struct imx_drm_device *imxdrm = drm->dev_private;
 
-	drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
+	if (imxdrm->fbhelper) {
+		drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
+	} else {
+		struct drm_connector *connector;
+
+		/* no kernel mode to go back to, disable all outputs */
+		drm_modeset_lock_all(drm);
+		drm_for_each_connector(connector, drm)
+			connector->encoder = NULL;
+		drm_modeset_unlock_all(drm);
+
+		drm_helper_disable_unused_functions(drm);
+	}
 }
 
 static int imx_drm_driver_unload(struct drm_device *drm)
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 2/5] drm/imx: imx-ldb: check return code on panel attach
  2016-06-17 10:13 [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Lucas Stach
@ 2016-06-17 10:13 ` Lucas Stach
  2016-07-11 10:25   ` Philipp Zabel
  2016-06-17 10:13 ` [PATCH 3/5] drm/imx: imx-ldb: detach panel on unbind Lucas Stach
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Lucas Stach @ 2016-06-17 10:13 UTC (permalink / raw)
  To: Philipp Zabel; +Cc: kernel, dri-devel, patchwork-lst

Check the return code on panel attach. Avoids a kernel crash later
on if the attach failed.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/gpu/drm/imx/imx-ldb.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index beff793bb717..48166df14042 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -427,8 +427,12 @@ static int imx_ldb_register(struct drm_device *drm,
 	drm_connector_init(drm, &imx_ldb_ch->connector,
 			   &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
 
-	if (imx_ldb_ch->panel)
-		drm_panel_attach(imx_ldb_ch->panel, &imx_ldb_ch->connector);
+	if (imx_ldb_ch->panel) {
+		ret = drm_panel_attach(imx_ldb_ch->panel,
+				       &imx_ldb_ch->connector);
+		if (ret)
+			return ret;
+	}
 
 	drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
 			&imx_ldb_ch->encoder);
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 3/5] drm/imx: imx-ldb: detach panel on unbind
  2016-06-17 10:13 [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Lucas Stach
  2016-06-17 10:13 ` [PATCH 2/5] drm/imx: imx-ldb: check return code on panel attach Lucas Stach
@ 2016-06-17 10:13 ` Lucas Stach
  2016-06-20 12:03   ` Philipp Zabel
  2016-06-17 10:13 ` [PATCH 4/5] drm/imx: drop deprecated load/unload drm_driver ops Lucas Stach
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Lucas Stach @ 2016-06-17 10:13 UTC (permalink / raw)
  To: Philipp Zabel; +Cc: kernel, dri-devel, patchwork-lst

Make sure to leave a clean panel state behind and allow to
properly attach to the panel again on a rebind.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/gpu/drm/imx/imx-ldb.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 48166df14042..9e117a654417 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -671,6 +671,9 @@ static void imx_ldb_unbind(struct device *dev, struct device *master,
 	for (i = 0; i < 2; i++) {
 		struct imx_ldb_channel *channel = &imx_ldb->channel[i];
 
+		if (channel->panel)
+			drm_panel_detach(channel->panel);
+
 		if (!channel->connector.funcs)
 			continue;
 
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 4/5] drm/imx: drop deprecated load/unload drm_driver ops
  2016-06-17 10:13 [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Lucas Stach
  2016-06-17 10:13 ` [PATCH 2/5] drm/imx: imx-ldb: check return code on panel attach Lucas Stach
  2016-06-17 10:13 ` [PATCH 3/5] drm/imx: imx-ldb: detach panel on unbind Lucas Stach
@ 2016-06-17 10:13 ` Lucas Stach
  2016-06-17 12:48   ` Daniel Vetter
  2016-06-17 10:13 ` [PATCH 5/5] drm/imx: don't destroy mode objects manually on driver unbind Lucas Stach
  2016-06-17 12:45 ` [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Daniel Vetter
  4 siblings, 1 reply; 11+ messages in thread
From: Lucas Stach @ 2016-06-17 10:13 UTC (permalink / raw)
  To: Philipp Zabel; +Cc: kernel, dri-devel, patchwork-lst

Drop the load/unload driver ops, as they are deprecated because of their
inherent races, with devices being visible to userspace before they are
fully initialized.

Move this code into the driver bind/unbind routines bracketed by the
proper drm_dev_alloc/register and drm_dev_unregister/unref calls.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/gpu/drm/imx/imx-drm-core.c | 247 ++++++++++++++++++-------------------
 1 file changed, 121 insertions(+), 126 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index c63378661e11..799a68976590 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -78,25 +78,6 @@ static void imx_drm_driver_lastclose(struct drm_device *drm)
 	}
 }
 
-static int imx_drm_driver_unload(struct drm_device *drm)
-{
-	struct imx_drm_device *imxdrm = drm->dev_private;
-
-	drm_kms_helper_poll_fini(drm);
-
-	if (imxdrm->fbhelper)
-		drm_fbdev_cma_fini(imxdrm->fbhelper);
-
-	component_unbind_all(drm->dev, drm);
-
-	drm_vblank_cleanup(drm);
-	drm_mode_config_cleanup(drm);
-
-	platform_set_drvdata(drm->platformdev, NULL);
-
-	return 0;
-}
-
 static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
 {
 	struct imx_drm_device *imxdrm = crtc->dev->dev_private;
@@ -223,109 +204,6 @@ static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = {
 };
 
 /*
- * Main DRM initialisation. This binds, initialises and registers
- * with DRM the subcomponents of the driver.
- */
-static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
-{
-	struct imx_drm_device *imxdrm;
-	struct drm_connector *connector;
-	int ret;
-
-	imxdrm = devm_kzalloc(drm->dev, sizeof(*imxdrm), GFP_KERNEL);
-	if (!imxdrm)
-		return -ENOMEM;
-
-	imxdrm->drm = drm;
-
-	drm->dev_private = imxdrm;
-
-	/*
-	 * enable drm irq mode.
-	 * - with irq_enabled = true, we can use the vblank feature.
-	 *
-	 * P.S. note that we wouldn't use drm irq handler but
-	 *      just specific driver own one instead because
-	 *      drm framework supports only one irq handler and
-	 *      drivers can well take care of their interrupts
-	 */
-	drm->irq_enabled = true;
-
-	/*
-	 * set max width and height as default value(4096x4096).
-	 * this value would be used to check framebuffer size limitation
-	 * at drm_mode_addfb().
-	 */
-	drm->mode_config.min_width = 64;
-	drm->mode_config.min_height = 64;
-	drm->mode_config.max_width = 4096;
-	drm->mode_config.max_height = 4096;
-	drm->mode_config.funcs = &imx_drm_mode_config_funcs;
-
-	drm_mode_config_init(drm);
-
-	ret = drm_vblank_init(drm, MAX_CRTC);
-	if (ret)
-		goto err_kms;
-
-	platform_set_drvdata(drm->platformdev, drm);
-
-	/* Now try and bind all our sub-components */
-	ret = component_bind_all(drm->dev, drm);
-	if (ret)
-		goto err_vblank;
-
-	/*
-	 * All components are now added, we can publish the connector sysfs
-	 * entries to userspace.  This will generate hotplug events and so
-	 * userspace will expect to be able to access DRM at this point.
-	 */
-	list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
-		ret = drm_connector_register(connector);
-		if (ret) {
-			dev_err(drm->dev,
-				"[CONNECTOR:%d:%s] drm_connector_register failed: %d\n",
-				connector->base.id,
-				connector->name, ret);
-			goto err_unbind;
-		}
-	}
-
-	/*
-	 * All components are now initialised, so setup the fb helper.
-	 * The fb helper takes copies of key hardware information, so the
-	 * crtcs/connectors/encoders must not change after this point.
-	 */
-#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
-	if (legacyfb_depth != 16 && legacyfb_depth != 32) {
-		dev_warn(drm->dev, "Invalid legacyfb_depth.  Defaulting to 16bpp\n");
-		legacyfb_depth = 16;
-	}
-	drm_helper_disable_unused_functions(drm);
-	imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
-				drm->mode_config.num_crtc, MAX_CRTC);
-	if (IS_ERR(imxdrm->fbhelper)) {
-		ret = PTR_ERR(imxdrm->fbhelper);
-		imxdrm->fbhelper = NULL;
-		goto err_unbind;
-	}
-#endif
-
-	drm_kms_helper_poll_init(drm);
-
-	return 0;
-
-err_unbind:
-	component_unbind_all(drm->dev, drm);
-err_vblank:
-	drm_vblank_cleanup(drm);
-err_kms:
-	drm_mode_config_cleanup(drm);
-
-	return ret;
-}
-
-/*
  * imx_drm_add_crtc - add a new crtc
  */
 int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
@@ -416,8 +294,6 @@ static const struct drm_ioctl_desc imx_drm_ioctls[] = {
 
 static struct drm_driver imx_drm_driver = {
 	.driver_features	= DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
-	.load			= imx_drm_driver_load,
-	.unload			= imx_drm_driver_unload,
 	.lastclose		= imx_drm_driver_lastclose,
 	.set_busid		= drm_platform_set_busid,
 	.gem_free_object_unlocked = drm_gem_cma_free_object,
@@ -471,12 +347,131 @@ static int compare_of(struct device *dev, void *data)
 
 static int imx_drm_bind(struct device *dev)
 {
-	return drm_platform_init(&imx_drm_driver, to_platform_device(dev));
+	struct drm_device *drm;
+	struct imx_drm_device *imxdrm;
+	int ret;
+
+	drm = drm_dev_alloc(&imx_drm_driver, dev);
+	if (!drm)
+		return -ENOMEM;
+
+	imxdrm = devm_kzalloc(dev, sizeof(*imxdrm), GFP_KERNEL);
+	if (!imxdrm) {
+		ret = -ENOMEM;
+		goto err_unref;
+	}
+
+	imxdrm->drm = drm;
+	drm->dev_private = imxdrm;
+
+	/*
+	 * enable drm irq mode.
+	 * - with irq_enabled = true, we can use the vblank feature.
+	 *
+	 * P.S. note that we wouldn't use drm irq handler but
+	 *      just specific driver own one instead because
+	 *      drm framework supports only one irq handler and
+	 *      drivers can well take care of their interrupts
+	 */
+	drm->irq_enabled = true;
+
+	/*
+	 * set max width and height as default value(4096x4096).
+	 * this value would be used to check framebuffer size limitation
+	 * at drm_mode_addfb().
+	 */
+	drm->mode_config.min_width = 64;
+	drm->mode_config.min_height = 64;
+	drm->mode_config.max_width = 4096;
+	drm->mode_config.max_height = 4096;
+	drm->mode_config.funcs = &imx_drm_mode_config_funcs;
+
+	drm_mode_config_init(drm);
+
+	ret = drm_vblank_init(drm, MAX_CRTC);
+	if (ret)
+		goto err_kms;
+
+	dev_set_drvdata(dev, drm);
+
+	/* Now try and bind all our sub-components */
+	ret = component_bind_all(dev, drm);
+	if (ret)
+		goto err_vblank;
+
+	ret = drm_dev_register(drm, 0);
+	if (ret)
+		goto err_unbind;
+
+	/*
+	 * All components are now added, we can publish the connector sysfs
+	 * entries to userspace.  This will generate hotplug events and so
+	 * userspace will expect to be able to access DRM at this point.
+	 */
+	ret = drm_connector_register_all(drm);
+	if (ret)
+		goto err_unregister;
+
+	/*
+	 * All components are now initialised, so setup the fb helper.
+	 * The fb helper takes copies of key hardware information, so the
+	 * crtcs/connectors/encoders must not change after this point.
+	 */
+#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
+	if (legacyfb_depth != 16 && legacyfb_depth != 32) {
+		dev_warn(dev, "Invalid legacyfb_depth.  Defaulting to 16bpp\n");
+		legacyfb_depth = 16;
+	}
+	drm_helper_disable_unused_functions(drm);
+	imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
+				drm->mode_config.num_crtc, MAX_CRTC);
+	if (IS_ERR(imxdrm->fbhelper)) {
+		ret = PTR_ERR(imxdrm->fbhelper);
+		imxdrm->fbhelper = NULL;
+		goto err_unregister;
+	}
+#endif
+
+	drm_kms_helper_poll_init(drm);
+
+	return 0;
+
+err_unregister:
+	drm_dev_unregister(drm);
+err_unbind:
+	component_unbind_all(drm->dev, drm);
+err_vblank:
+	drm_vblank_cleanup(drm);
+err_kms:
+	drm_mode_config_cleanup(drm);
+err_unref:
+	drm_dev_unref(drm);
+
+	return ret;
 }
 
 static void imx_drm_unbind(struct device *dev)
 {
-	drm_put_dev(dev_get_drvdata(dev));
+	struct drm_device *drm = dev_get_drvdata(dev);
+	struct imx_drm_device *imxdrm = drm->dev_private;
+	struct drm_fbdev_cma *fbhelper = imxdrm->fbhelper;
+
+	drm_kms_helper_poll_fini(drm);
+	/* device is going down, so no need to restore fbdev modes */
+	imxdrm->fbhelper = NULL;
+
+	drm_connector_unregister_all(drm);
+	drm_dev_unregister(drm);
+
+	if (fbhelper)
+		drm_fbdev_cma_fini(fbhelper);
+
+	component_unbind_all(drm->dev, drm);
+	dev_set_drvdata(dev, NULL);
+
+	drm_mode_config_cleanup(drm);
+
+	drm_dev_unref(drm);
 }
 
 static const struct component_master_ops imx_drm_ops = {
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 5/5] drm/imx: don't destroy mode objects manually on driver unbind
  2016-06-17 10:13 [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Lucas Stach
                   ` (2 preceding siblings ...)
  2016-06-17 10:13 ` [PATCH 4/5] drm/imx: drop deprecated load/unload drm_driver ops Lucas Stach
@ 2016-06-17 10:13 ` Lucas Stach
  2016-06-20 12:00   ` Philipp Zabel
  2016-06-17 12:45 ` [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Daniel Vetter
  4 siblings, 1 reply; 11+ messages in thread
From: Lucas Stach @ 2016-06-17 10:13 UTC (permalink / raw)
  To: Philipp Zabel; +Cc: kernel, dri-devel, patchwork-lst

Instead let drm_mode_config_cleanup() do the work when taking down
the master device. This requires all cleanup functions to be
properly hooked up to the mode object .destroy callback.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/gpu/drm/bridge/dw-hdmi.c       | 3 ---
 drivers/gpu/drm/imx/imx-drm-core.c     | 4 ++--
 drivers/gpu/drm/imx/imx-ldb.c          | 6 ------
 drivers/gpu/drm/imx/imx-tve.c          | 3 ---
 drivers/gpu/drm/imx/ipuv3-crtc.c       | 9 ++++++---
 drivers/gpu/drm/imx/parallel-display.c | 3 ---
 6 files changed, 8 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index c9d941283d30..5f97977f7e5c 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1834,9 +1834,6 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
 	/* Disable all interrupts */
 	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
 
-	hdmi->connector.funcs->destroy(&hdmi->connector);
-	hdmi->encoder->funcs->destroy(hdmi->encoder);
-
 	clk_disable_unprepare(hdmi->iahb_clk);
 	clk_disable_unprepare(hdmi->isfr_clk);
 	i2c_put_adapter(hdmi->ddc);
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index 799a68976590..71e33666cae8 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -466,11 +466,11 @@ static void imx_drm_unbind(struct device *dev)
 	if (fbhelper)
 		drm_fbdev_cma_fini(fbhelper);
 
+	drm_mode_config_cleanup(drm);
+
 	component_unbind_all(drm->dev, drm);
 	dev_set_drvdata(dev, NULL);
 
-	drm_mode_config_cleanup(drm);
-
 	drm_dev_unref(drm);
 }
 
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 9e117a654417..b49948d51110 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -674,12 +674,6 @@ static void imx_ldb_unbind(struct device *dev, struct device *master,
 		if (channel->panel)
 			drm_panel_detach(channel->panel);
 
-		if (!channel->connector.funcs)
-			continue;
-
-		channel->connector.funcs->destroy(&channel->connector);
-		channel->encoder.funcs->destroy(&channel->encoder);
-
 		kfree(channel->edid);
 		i2c_put_adapter(channel->ddc);
 	}
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index baf788121287..3973b2c85e2d 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -688,9 +688,6 @@ static void imx_tve_unbind(struct device *dev, struct device *master,
 {
 	struct imx_tve *tve = dev_get_drvdata(dev);
 
-	tve->connector.funcs->destroy(&tve->connector);
-	tve->encoder.funcs->destroy(&tve->encoder);
-
 	if (!IS_ERR(tve->dac_reg))
 		regulator_disable(tve->dac_reg);
 }
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index fc040417e1e8..4d5dbea48cef 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -228,9 +228,14 @@ put_vblank:
 	return ret;
 }
 
+static void ipu_crtc_cleanup(struct drm_crtc *crtc)
+{
+	imx_drm_remove_crtc(to_ipu_crtc(crtc)->imx_crtc);
+}
+
 static const struct drm_crtc_funcs ipu_crtc_funcs = {
 	.set_config = drm_crtc_helper_set_config,
-	.destroy = drm_crtc_cleanup,
+	.destroy = ipu_crtc_cleanup,
 	.page_flip = ipu_page_flip,
 };
 
@@ -551,8 +556,6 @@ static void ipu_drm_unbind(struct device *dev, struct device *master,
 {
 	struct ipu_crtc *ipu_crtc = dev_get_drvdata(dev);
 
-	imx_drm_remove_crtc(ipu_crtc->imx_crtc);
-
 	destroy_workqueue(ipu_crtc->flip_queue);
 	ipu_plane_put_resources(ipu_crtc->plane[0]);
 	ipu_put_resources(ipu_crtc);
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index 2d1fd02cd3d6..a1fa8fc91336 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -248,9 +248,6 @@ static void imx_pd_unbind(struct device *dev, struct device *master,
 {
 	struct imx_parallel_display *imxpd = dev_get_drvdata(dev);
 
-	imxpd->encoder.funcs->destroy(&imxpd->encoder);
-	imxpd->connector.funcs->destroy(&imxpd->connector);
-
 	kfree(imxpd->edid);
 }
 
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled
  2016-06-17 10:13 [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Lucas Stach
                   ` (3 preceding siblings ...)
  2016-06-17 10:13 ` [PATCH 5/5] drm/imx: don't destroy mode objects manually on driver unbind Lucas Stach
@ 2016-06-17 12:45 ` Daniel Vetter
  4 siblings, 0 replies; 11+ messages in thread
From: Daniel Vetter @ 2016-06-17 12:45 UTC (permalink / raw)
  To: Lucas Stach; +Cc: dri-devel, kernel, patchwork-lst

On Fri, Jun 17, 2016 at 12:13:38PM +0200, Lucas Stach wrote:
> If there is no framebuffer mode that can be restored, all outputs should
> be disabled in order to avoid information leaks.

No, this was a short-term regression that's now fixed again. When a client
closes or calls rmfb, we make sure that buffer isn't in use any more. This
shouldn't be needed any more.

Also, a generic fix in driver code. Tsk! ;-)

Cheers, Daniel

> 
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> ---
>  drivers/gpu/drm/imx/imx-drm-core.c | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
> index 82656654fb21..c63378661e11 100644
> --- a/drivers/gpu/drm/imx/imx-drm-core.c
> +++ b/drivers/gpu/drm/imx/imx-drm-core.c
> @@ -63,7 +63,19 @@ static void imx_drm_driver_lastclose(struct drm_device *drm)
>  {
>  	struct imx_drm_device *imxdrm = drm->dev_private;
>  
> -	drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
> +	if (imxdrm->fbhelper) {
> +		drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
> +	} else {
> +		struct drm_connector *connector;
> +
> +		/* no kernel mode to go back to, disable all outputs */
> +		drm_modeset_lock_all(drm);
> +		drm_for_each_connector(connector, drm)
> +			connector->encoder = NULL;
> +		drm_modeset_unlock_all(drm);
> +
> +		drm_helper_disable_unused_functions(drm);
> +	}
>  }
>  
>  static int imx_drm_driver_unload(struct drm_device *drm)
> -- 
> 2.8.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 4/5] drm/imx: drop deprecated load/unload drm_driver ops
  2016-06-17 10:13 ` [PATCH 4/5] drm/imx: drop deprecated load/unload drm_driver ops Lucas Stach
@ 2016-06-17 12:48   ` Daniel Vetter
  2016-06-24  7:46     ` Ying Liu
  0 siblings, 1 reply; 11+ messages in thread
From: Daniel Vetter @ 2016-06-17 12:48 UTC (permalink / raw)
  To: Lucas Stach; +Cc: dri-devel, kernel, patchwork-lst

On Fri, Jun 17, 2016 at 12:13:41PM +0200, Lucas Stach wrote:
> Drop the load/unload driver ops, as they are deprecated because of their
> inherent races, with devices being visible to userspace before they are
> fully initialized.
> 
> Move this code into the driver bind/unbind routines bracketed by the
> proper drm_dev_alloc/register and drm_dev_unregister/unref calls.
> 
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> ---
>  drivers/gpu/drm/imx/imx-drm-core.c | 247 ++++++++++++++++++-------------------
>  1 file changed, 121 insertions(+), 126 deletions(-)
> 
> diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
> index c63378661e11..799a68976590 100644
> --- a/drivers/gpu/drm/imx/imx-drm-core.c
> +++ b/drivers/gpu/drm/imx/imx-drm-core.c
> @@ -78,25 +78,6 @@ static void imx_drm_driver_lastclose(struct drm_device *drm)
>  	}
>  }
>  
> -static int imx_drm_driver_unload(struct drm_device *drm)
> -{
> -	struct imx_drm_device *imxdrm = drm->dev_private;
> -
> -	drm_kms_helper_poll_fini(drm);
> -
> -	if (imxdrm->fbhelper)
> -		drm_fbdev_cma_fini(imxdrm->fbhelper);
> -
> -	component_unbind_all(drm->dev, drm);
> -
> -	drm_vblank_cleanup(drm);
> -	drm_mode_config_cleanup(drm);
> -
> -	platform_set_drvdata(drm->platformdev, NULL);
> -
> -	return 0;
> -}
> -
>  static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
>  {
>  	struct imx_drm_device *imxdrm = crtc->dev->dev_private;
> @@ -223,109 +204,6 @@ static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = {
>  };
>  
>  /*
> - * Main DRM initialisation. This binds, initialises and registers
> - * with DRM the subcomponents of the driver.
> - */
> -static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
> -{
> -	struct imx_drm_device *imxdrm;
> -	struct drm_connector *connector;
> -	int ret;
> -
> -	imxdrm = devm_kzalloc(drm->dev, sizeof(*imxdrm), GFP_KERNEL);
> -	if (!imxdrm)
> -		return -ENOMEM;
> -
> -	imxdrm->drm = drm;
> -
> -	drm->dev_private = imxdrm;
> -
> -	/*
> -	 * enable drm irq mode.
> -	 * - with irq_enabled = true, we can use the vblank feature.
> -	 *
> -	 * P.S. note that we wouldn't use drm irq handler but
> -	 *      just specific driver own one instead because
> -	 *      drm framework supports only one irq handler and
> -	 *      drivers can well take care of their interrupts
> -	 */
> -	drm->irq_enabled = true;
> -
> -	/*
> -	 * set max width and height as default value(4096x4096).
> -	 * this value would be used to check framebuffer size limitation
> -	 * at drm_mode_addfb().
> -	 */
> -	drm->mode_config.min_width = 64;
> -	drm->mode_config.min_height = 64;
> -	drm->mode_config.max_width = 4096;
> -	drm->mode_config.max_height = 4096;
> -	drm->mode_config.funcs = &imx_drm_mode_config_funcs;
> -
> -	drm_mode_config_init(drm);
> -
> -	ret = drm_vblank_init(drm, MAX_CRTC);
> -	if (ret)
> -		goto err_kms;
> -
> -	platform_set_drvdata(drm->platformdev, drm);
> -
> -	/* Now try and bind all our sub-components */
> -	ret = component_bind_all(drm->dev, drm);
> -	if (ret)
> -		goto err_vblank;
> -
> -	/*
> -	 * All components are now added, we can publish the connector sysfs
> -	 * entries to userspace.  This will generate hotplug events and so
> -	 * userspace will expect to be able to access DRM at this point.
> -	 */
> -	list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
> -		ret = drm_connector_register(connector);
> -		if (ret) {
> -			dev_err(drm->dev,
> -				"[CONNECTOR:%d:%s] drm_connector_register failed: %d\n",
> -				connector->base.id,
> -				connector->name, ret);
> -			goto err_unbind;
> -		}
> -	}
> -
> -	/*
> -	 * All components are now initialised, so setup the fb helper.
> -	 * The fb helper takes copies of key hardware information, so the
> -	 * crtcs/connectors/encoders must not change after this point.
> -	 */
> -#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
> -	if (legacyfb_depth != 16 && legacyfb_depth != 32) {
> -		dev_warn(drm->dev, "Invalid legacyfb_depth.  Defaulting to 16bpp\n");
> -		legacyfb_depth = 16;
> -	}
> -	drm_helper_disable_unused_functions(drm);
> -	imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
> -				drm->mode_config.num_crtc, MAX_CRTC);
> -	if (IS_ERR(imxdrm->fbhelper)) {
> -		ret = PTR_ERR(imxdrm->fbhelper);
> -		imxdrm->fbhelper = NULL;
> -		goto err_unbind;
> -	}
> -#endif
> -
> -	drm_kms_helper_poll_init(drm);
> -
> -	return 0;
> -
> -err_unbind:
> -	component_unbind_all(drm->dev, drm);
> -err_vblank:
> -	drm_vblank_cleanup(drm);
> -err_kms:
> -	drm_mode_config_cleanup(drm);
> -
> -	return ret;
> -}
> -
> -/*
>   * imx_drm_add_crtc - add a new crtc
>   */
>  int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
> @@ -416,8 +294,6 @@ static const struct drm_ioctl_desc imx_drm_ioctls[] = {
>  
>  static struct drm_driver imx_drm_driver = {
>  	.driver_features	= DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
> -	.load			= imx_drm_driver_load,
> -	.unload			= imx_drm_driver_unload,
>  	.lastclose		= imx_drm_driver_lastclose,
>  	.set_busid		= drm_platform_set_busid,
>  	.gem_free_object_unlocked = drm_gem_cma_free_object,
> @@ -471,12 +347,131 @@ static int compare_of(struct device *dev, void *data)
>  
>  static int imx_drm_bind(struct device *dev)
>  {
> -	return drm_platform_init(&imx_drm_driver, to_platform_device(dev));
> +	struct drm_device *drm;
> +	struct imx_drm_device *imxdrm;
> +	int ret;
> +
> +	drm = drm_dev_alloc(&imx_drm_driver, dev);
> +	if (!drm)
> +		return -ENOMEM;
> +
> +	imxdrm = devm_kzalloc(dev, sizeof(*imxdrm), GFP_KERNEL);
> +	if (!imxdrm) {
> +		ret = -ENOMEM;
> +		goto err_unref;
> +	}
> +
> +	imxdrm->drm = drm;
> +	drm->dev_private = imxdrm;
> +
> +	/*
> +	 * enable drm irq mode.
> +	 * - with irq_enabled = true, we can use the vblank feature.
> +	 *
> +	 * P.S. note that we wouldn't use drm irq handler but
> +	 *      just specific driver own one instead because
> +	 *      drm framework supports only one irq handler and
> +	 *      drivers can well take care of their interrupts
> +	 */
> +	drm->irq_enabled = true;
> +
> +	/*
> +	 * set max width and height as default value(4096x4096).
> +	 * this value would be used to check framebuffer size limitation
> +	 * at drm_mode_addfb().
> +	 */
> +	drm->mode_config.min_width = 64;
> +	drm->mode_config.min_height = 64;
> +	drm->mode_config.max_width = 4096;
> +	drm->mode_config.max_height = 4096;
> +	drm->mode_config.funcs = &imx_drm_mode_config_funcs;
> +
> +	drm_mode_config_init(drm);
> +
> +	ret = drm_vblank_init(drm, MAX_CRTC);
> +	if (ret)
> +		goto err_kms;
> +
> +	dev_set_drvdata(dev, drm);
> +
> +	/* Now try and bind all our sub-components */
> +	ret = component_bind_all(dev, drm);
> +	if (ret)
> +		goto err_vblank;
> +
> +	ret = drm_dev_register(drm, 0);

In principle this should be the last step in the init sequence, otherwise
you might have userspace fighting with your init code over the hw. Please
move down.

> +	if (ret)
> +		goto err_unbind;
> +
> +	/*
> +	 * All components are now added, we can publish the connector sysfs
> +	 * entries to userspace.  This will generate hotplug events and so
> +	 * userspace will expect to be able to access DRM at this point.
> +	 */
> +	ret = drm_connector_register_all(drm);

This (and connector_unregister_all) just became unecessary with the
patches from Chris that I merged into drm-misc today. Please remove.

> +	if (ret)
> +		goto err_unregister;
> +
> +	/*
> +	 * All components are now initialised, so setup the fb helper.
> +	 * The fb helper takes copies of key hardware information, so the
> +	 * crtcs/connectors/encoders must not change after this point.
> +	 */
> +#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
> +	if (legacyfb_depth != 16 && legacyfb_depth != 32) {
> +		dev_warn(dev, "Invalid legacyfb_depth.  Defaulting to 16bpp\n");
> +		legacyfb_depth = 16;
> +	}
> +	drm_helper_disable_unused_functions(drm);

fyi, you need to nuke this when switching to atomic.

> +	imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
> +				drm->mode_config.num_crtc, MAX_CRTC);
> +	if (IS_ERR(imxdrm->fbhelper)) {
> +		ret = PTR_ERR(imxdrm->fbhelper);
> +		imxdrm->fbhelper = NULL;
> +		goto err_unregister;
> +	}
> +#endif
> +
> +	drm_kms_helper_poll_init(drm);
> +
> +	return 0;
> +
> +err_unregister:
> +	drm_dev_unregister(drm);
> +err_unbind:
> +	component_unbind_all(drm->dev, drm);
> +err_vblank:
> +	drm_vblank_cleanup(drm);
> +err_kms:
> +	drm_mode_config_cleanup(drm);
> +err_unref:
> +	drm_dev_unref(drm);
> +
> +	return ret;
>  }
>  
>  static void imx_drm_unbind(struct device *dev)
>  {
> -	drm_put_dev(dev_get_drvdata(dev));
> +	struct drm_device *drm = dev_get_drvdata(dev);
> +	struct imx_drm_device *imxdrm = drm->dev_private;
> +	struct drm_fbdev_cma *fbhelper = imxdrm->fbhelper;
> +
> +	drm_kms_helper_poll_fini(drm);
> +	/* device is going down, so no need to restore fbdev modes */
> +	imxdrm->fbhelper = NULL;
> +
> +	drm_connector_unregister_all(drm);
> +	drm_dev_unregister(drm);

Same here: unregister should be first, connector_unregister_all isn't
needed any more.
-Daniel

> +
> +	if (fbhelper)
> +		drm_fbdev_cma_fini(fbhelper);
> +
> +	component_unbind_all(drm->dev, drm);
> +	dev_set_drvdata(dev, NULL);
> +
> +	drm_mode_config_cleanup(drm);
> +
> +	drm_dev_unref(drm);
>  }
>  
>  static const struct component_master_ops imx_drm_ops = {
> -- 
> 2.8.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 5/5] drm/imx: don't destroy mode objects manually on driver unbind
  2016-06-17 10:13 ` [PATCH 5/5] drm/imx: don't destroy mode objects manually on driver unbind Lucas Stach
@ 2016-06-20 12:00   ` Philipp Zabel
  0 siblings, 0 replies; 11+ messages in thread
From: Philipp Zabel @ 2016-06-20 12:00 UTC (permalink / raw)
  To: Lucas Stach; +Cc: kernel, dri-devel, patchwork-lst

Am Freitag, den 17.06.2016, 12:13 +0200 schrieb Lucas Stach:
> Instead let drm_mode_config_cleanup() do the work when taking down
> the master device. This requires all cleanup functions to be
> properly hooked up to the mode object .destroy callback.
> 
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> ---
>  drivers/gpu/drm/bridge/dw-hdmi.c       | 3 ---
>  drivers/gpu/drm/imx/imx-drm-core.c     | 4 ++--
>  drivers/gpu/drm/imx/imx-ldb.c          | 6 ------
>  drivers/gpu/drm/imx/imx-tve.c          | 3 ---
>  drivers/gpu/drm/imx/ipuv3-crtc.c       | 9 ++++++---
>  drivers/gpu/drm/imx/parallel-display.c | 3 ---
>  6 files changed, 8 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index c9d941283d30..5f97977f7e5c 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -1834,9 +1834,6 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
>  	/* Disable all interrupts */
>  	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
>  
> -	hdmi->connector.funcs->destroy(&hdmi->connector);
> -	hdmi->encoder->funcs->destroy(hdmi->encoder);
> -
>  	clk_disable_unprepare(hdmi->iahb_clk);
>  	clk_disable_unprepare(hdmi->isfr_clk);
>  	i2c_put_adapter(hdmi->ddc);

The rockchip driver already calls drm_mode_config_cleanup after
component_unbind_all, so I this change should work for the rockchip
driver as is?

> diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
> index 799a68976590..71e33666cae8 100644
> --- a/drivers/gpu/drm/imx/imx-drm-core.c
> +++ b/drivers/gpu/drm/imx/imx-drm-core.c
> @@ -466,11 +466,11 @@ static void imx_drm_unbind(struct device *dev)
>  	if (fbhelper)
>  		drm_fbdev_cma_fini(fbhelper);
>  
> +	drm_mode_config_cleanup(drm);
> +
>  	component_unbind_all(drm->dev, drm);
>  	dev_set_drvdata(dev, NULL);
>  
> -	drm_mode_config_cleanup(drm);
> -
>  	drm_dev_unref(drm);
>  }

regards
Philipp

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 3/5] drm/imx: imx-ldb: detach panel on unbind
  2016-06-17 10:13 ` [PATCH 3/5] drm/imx: imx-ldb: detach panel on unbind Lucas Stach
@ 2016-06-20 12:03   ` Philipp Zabel
  0 siblings, 0 replies; 11+ messages in thread
From: Philipp Zabel @ 2016-06-20 12:03 UTC (permalink / raw)
  To: Lucas Stach; +Cc: kernel, dri-devel, patchwork-lst

Am Freitag, den 17.06.2016, 12:13 +0200 schrieb Lucas Stach:
> Make sure to leave a clean panel state behind and allow to
> properly attach to the panel again on a rebind.
> 
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> ---
>  drivers/gpu/drm/imx/imx-ldb.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
> index 48166df14042..9e117a654417 100644
> --- a/drivers/gpu/drm/imx/imx-ldb.c
> +++ b/drivers/gpu/drm/imx/imx-ldb.c
> @@ -671,6 +671,9 @@ static void imx_ldb_unbind(struct device *dev, struct device *master,
>  	for (i = 0; i < 2; i++) {
>  		struct imx_ldb_channel *channel = &imx_ldb->channel[i];
>  
> +		if (channel->panel)
> +			drm_panel_detach(channel->panel);

I think this should also be done in the bind error path.

regards
Philipp

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 4/5] drm/imx: drop deprecated load/unload drm_driver ops
  2016-06-17 12:48   ` Daniel Vetter
@ 2016-06-24  7:46     ` Ying Liu
  0 siblings, 0 replies; 11+ messages in thread
From: Ying Liu @ 2016-06-24  7:46 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: patchwork-lst, kernel, DRI Development

On Fri, Jun 17, 2016 at 8:48 PM, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Fri, Jun 17, 2016 at 12:13:41PM +0200, Lucas Stach wrote:
>> Drop the load/unload driver ops, as they are deprecated because of their
>> inherent races, with devices being visible to userspace before they are
>> fully initialized.
>>
>> Move this code into the driver bind/unbind routines bracketed by the
>> proper drm_dev_alloc/register and drm_dev_unregister/unref calls.
>>
>> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
>> ---
>>  drivers/gpu/drm/imx/imx-drm-core.c | 247 ++++++++++++++++++-------------------
>>  1 file changed, 121 insertions(+), 126 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
>> index c63378661e11..799a68976590 100644
>> --- a/drivers/gpu/drm/imx/imx-drm-core.c
>> +++ b/drivers/gpu/drm/imx/imx-drm-core.c
>> @@ -78,25 +78,6 @@ static void imx_drm_driver_lastclose(struct drm_device *drm)
>>       }
>>  }
>>
>> -static int imx_drm_driver_unload(struct drm_device *drm)
>> -{
>> -     struct imx_drm_device *imxdrm = drm->dev_private;
>> -
>> -     drm_kms_helper_poll_fini(drm);
>> -
>> -     if (imxdrm->fbhelper)
>> -             drm_fbdev_cma_fini(imxdrm->fbhelper);
>> -
>> -     component_unbind_all(drm->dev, drm);
>> -
>> -     drm_vblank_cleanup(drm);
>> -     drm_mode_config_cleanup(drm);
>> -
>> -     platform_set_drvdata(drm->platformdev, NULL);
>> -
>> -     return 0;
>> -}
>> -
>>  static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
>>  {
>>       struct imx_drm_device *imxdrm = crtc->dev->dev_private;
>> @@ -223,109 +204,6 @@ static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = {
>>  };
>>
>>  /*
>> - * Main DRM initialisation. This binds, initialises and registers
>> - * with DRM the subcomponents of the driver.
>> - */
>> -static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
>> -{
>> -     struct imx_drm_device *imxdrm;
>> -     struct drm_connector *connector;
>> -     int ret;
>> -
>> -     imxdrm = devm_kzalloc(drm->dev, sizeof(*imxdrm), GFP_KERNEL);
>> -     if (!imxdrm)
>> -             return -ENOMEM;
>> -
>> -     imxdrm->drm = drm;
>> -
>> -     drm->dev_private = imxdrm;
>> -
>> -     /*
>> -      * enable drm irq mode.
>> -      * - with irq_enabled = true, we can use the vblank feature.
>> -      *
>> -      * P.S. note that we wouldn't use drm irq handler but
>> -      *      just specific driver own one instead because
>> -      *      drm framework supports only one irq handler and
>> -      *      drivers can well take care of their interrupts
>> -      */
>> -     drm->irq_enabled = true;
>> -
>> -     /*
>> -      * set max width and height as default value(4096x4096).
>> -      * this value would be used to check framebuffer size limitation
>> -      * at drm_mode_addfb().
>> -      */
>> -     drm->mode_config.min_width = 64;
>> -     drm->mode_config.min_height = 64;
>> -     drm->mode_config.max_width = 4096;
>> -     drm->mode_config.max_height = 4096;
>> -     drm->mode_config.funcs = &imx_drm_mode_config_funcs;
>> -
>> -     drm_mode_config_init(drm);
>> -
>> -     ret = drm_vblank_init(drm, MAX_CRTC);
>> -     if (ret)
>> -             goto err_kms;
>> -
>> -     platform_set_drvdata(drm->platformdev, drm);
>> -
>> -     /* Now try and bind all our sub-components */
>> -     ret = component_bind_all(drm->dev, drm);
>> -     if (ret)
>> -             goto err_vblank;
>> -
>> -     /*
>> -      * All components are now added, we can publish the connector sysfs
>> -      * entries to userspace.  This will generate hotplug events and so
>> -      * userspace will expect to be able to access DRM at this point.
>> -      */
>> -     list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
>> -             ret = drm_connector_register(connector);
>> -             if (ret) {
>> -                     dev_err(drm->dev,
>> -                             "[CONNECTOR:%d:%s] drm_connector_register failed: %d\n",
>> -                             connector->base.id,
>> -                             connector->name, ret);
>> -                     goto err_unbind;
>> -             }
>> -     }
>> -
>> -     /*
>> -      * All components are now initialised, so setup the fb helper.
>> -      * The fb helper takes copies of key hardware information, so the
>> -      * crtcs/connectors/encoders must not change after this point.
>> -      */
>> -#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
>> -     if (legacyfb_depth != 16 && legacyfb_depth != 32) {
>> -             dev_warn(drm->dev, "Invalid legacyfb_depth.  Defaulting to 16bpp\n");
>> -             legacyfb_depth = 16;
>> -     }
>> -     drm_helper_disable_unused_functions(drm);
>> -     imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
>> -                             drm->mode_config.num_crtc, MAX_CRTC);
>> -     if (IS_ERR(imxdrm->fbhelper)) {
>> -             ret = PTR_ERR(imxdrm->fbhelper);
>> -             imxdrm->fbhelper = NULL;
>> -             goto err_unbind;
>> -     }
>> -#endif
>> -
>> -     drm_kms_helper_poll_init(drm);
>> -
>> -     return 0;
>> -
>> -err_unbind:
>> -     component_unbind_all(drm->dev, drm);
>> -err_vblank:
>> -     drm_vblank_cleanup(drm);
>> -err_kms:
>> -     drm_mode_config_cleanup(drm);
>> -
>> -     return ret;
>> -}
>> -
>> -/*
>>   * imx_drm_add_crtc - add a new crtc
>>   */
>>  int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
>> @@ -416,8 +294,6 @@ static const struct drm_ioctl_desc imx_drm_ioctls[] = {
>>
>>  static struct drm_driver imx_drm_driver = {
>>       .driver_features        = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
>> -     .load                   = imx_drm_driver_load,
>> -     .unload                 = imx_drm_driver_unload,
>>       .lastclose              = imx_drm_driver_lastclose,
>>       .set_busid              = drm_platform_set_busid,
>>       .gem_free_object_unlocked = drm_gem_cma_free_object,
>> @@ -471,12 +347,131 @@ static int compare_of(struct device *dev, void *data)
>>
>>  static int imx_drm_bind(struct device *dev)
>>  {
>> -     return drm_platform_init(&imx_drm_driver, to_platform_device(dev));
>> +     struct drm_device *drm;
>> +     struct imx_drm_device *imxdrm;
>> +     int ret;
>> +
>> +     drm = drm_dev_alloc(&imx_drm_driver, dev);
>> +     if (!drm)
>> +             return -ENOMEM;
>> +
>> +     imxdrm = devm_kzalloc(dev, sizeof(*imxdrm), GFP_KERNEL);
>> +     if (!imxdrm) {
>> +             ret = -ENOMEM;
>> +             goto err_unref;
>> +     }
>> +
>> +     imxdrm->drm = drm;
>> +     drm->dev_private = imxdrm;
>> +
>> +     /*
>> +      * enable drm irq mode.
>> +      * - with irq_enabled = true, we can use the vblank feature.
>> +      *
>> +      * P.S. note that we wouldn't use drm irq handler but
>> +      *      just specific driver own one instead because
>> +      *      drm framework supports only one irq handler and
>> +      *      drivers can well take care of their interrupts
>> +      */
>> +     drm->irq_enabled = true;
>> +
>> +     /*
>> +      * set max width and height as default value(4096x4096).
>> +      * this value would be used to check framebuffer size limitation
>> +      * at drm_mode_addfb().
>> +      */
>> +     drm->mode_config.min_width = 64;
>> +     drm->mode_config.min_height = 64;
>> +     drm->mode_config.max_width = 4096;
>> +     drm->mode_config.max_height = 4096;
>> +     drm->mode_config.funcs = &imx_drm_mode_config_funcs;
>> +
>> +     drm_mode_config_init(drm);
>> +
>> +     ret = drm_vblank_init(drm, MAX_CRTC);
>> +     if (ret)
>> +             goto err_kms;
>> +
>> +     dev_set_drvdata(dev, drm);
>> +
>> +     /* Now try and bind all our sub-components */
>> +     ret = component_bind_all(dev, drm);
>> +     if (ret)
>> +             goto err_vblank;
>> +
>> +     ret = drm_dev_register(drm, 0);
>
> In principle this should be the last step in the init sequence, otherwise
> you might have userspace fighting with your init code over the hw. Please
> move down.
>
>> +     if (ret)
>> +             goto err_unbind;
>> +
>> +     /*
>> +      * All components are now added, we can publish the connector sysfs
>> +      * entries to userspace.  This will generate hotplug events and so
>> +      * userspace will expect to be able to access DRM at this point.
>> +      */
>> +     ret = drm_connector_register_all(drm);
>
> This (and connector_unregister_all) just became unecessary with the
> patches from Chris that I merged into drm-misc today. Please remove.
>
>> +     if (ret)
>> +             goto err_unregister;
>> +
>> +     /*
>> +      * All components are now initialised, so setup the fb helper.
>> +      * The fb helper takes copies of key hardware information, so the
>> +      * crtcs/connectors/encoders must not change after this point.
>> +      */
>> +#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
>> +     if (legacyfb_depth != 16 && legacyfb_depth != 32) {
>> +             dev_warn(dev, "Invalid legacyfb_depth.  Defaulting to 16bpp\n");
>> +             legacyfb_depth = 16;
>> +     }
>> +     drm_helper_disable_unused_functions(drm);
>
> fyi, you need to nuke this when switching to atomic.

I've got this done in my imx-drm atomic conversion v2 patch set.

Regards,
Liu Ying

>
>> +     imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
>> +                             drm->mode_config.num_crtc, MAX_CRTC);
>> +     if (IS_ERR(imxdrm->fbhelper)) {
>> +             ret = PTR_ERR(imxdrm->fbhelper);
>> +             imxdrm->fbhelper = NULL;
>> +             goto err_unregister;
>> +     }
>> +#endif
>> +
>> +     drm_kms_helper_poll_init(drm);
>> +
>> +     return 0;
>> +
>> +err_unregister:
>> +     drm_dev_unregister(drm);
>> +err_unbind:
>> +     component_unbind_all(drm->dev, drm);
>> +err_vblank:
>> +     drm_vblank_cleanup(drm);
>> +err_kms:
>> +     drm_mode_config_cleanup(drm);
>> +err_unref:
>> +     drm_dev_unref(drm);
>> +
>> +     return ret;
>>  }
>>
>>  static void imx_drm_unbind(struct device *dev)
>>  {
>> -     drm_put_dev(dev_get_drvdata(dev));
>> +     struct drm_device *drm = dev_get_drvdata(dev);
>> +     struct imx_drm_device *imxdrm = drm->dev_private;
>> +     struct drm_fbdev_cma *fbhelper = imxdrm->fbhelper;
>> +
>> +     drm_kms_helper_poll_fini(drm);
>> +     /* device is going down, so no need to restore fbdev modes */
>> +     imxdrm->fbhelper = NULL;
>> +
>> +     drm_connector_unregister_all(drm);
>> +     drm_dev_unregister(drm);
>
> Same here: unregister should be first, connector_unregister_all isn't
> needed any more.
> -Daniel
>
>> +
>> +     if (fbhelper)
>> +             drm_fbdev_cma_fini(fbhelper);
>> +
>> +     component_unbind_all(drm->dev, drm);
>> +     dev_set_drvdata(dev, NULL);
>> +
>> +     drm_mode_config_cleanup(drm);
>> +
>> +     drm_dev_unref(drm);
>>  }
>>
>>  static const struct component_master_ops imx_drm_ops = {
>> --
>> 2.8.1
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 2/5] drm/imx: imx-ldb: check return code on panel attach
  2016-06-17 10:13 ` [PATCH 2/5] drm/imx: imx-ldb: check return code on panel attach Lucas Stach
@ 2016-07-11 10:25   ` Philipp Zabel
  0 siblings, 0 replies; 11+ messages in thread
From: Philipp Zabel @ 2016-07-11 10:25 UTC (permalink / raw)
  To: Lucas Stach; +Cc: kernel, dri-devel, patchwork-lst

Am Freitag, den 17.06.2016, 12:13 +0200 schrieb Lucas Stach:
> Check the return code on panel attach. Avoids a kernel crash later
> on if the attach failed.
> 
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> ---
>  drivers/gpu/drm/imx/imx-ldb.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
> index beff793bb717..48166df14042 100644
> --- a/drivers/gpu/drm/imx/imx-ldb.c
> +++ b/drivers/gpu/drm/imx/imx-ldb.c
> @@ -427,8 +427,12 @@ static int imx_ldb_register(struct drm_device *drm,
>  	drm_connector_init(drm, &imx_ldb_ch->connector,
>  			   &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
>  
> -	if (imx_ldb_ch->panel)
> -		drm_panel_attach(imx_ldb_ch->panel, &imx_ldb_ch->connector);
> +	if (imx_ldb_ch->panel) {
> +		ret = drm_panel_attach(imx_ldb_ch->panel,
> +				       &imx_ldb_ch->connector);
> +		if (ret)
> +			return ret;
> +	}
>  
>  	drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
>  			&imx_ldb_ch->encoder);

Applied, thanks.

regards
Philipp

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

end of thread, other threads:[~2016-07-11 10:25 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-06-17 10:13 [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Lucas Stach
2016-06-17 10:13 ` [PATCH 2/5] drm/imx: imx-ldb: check return code on panel attach Lucas Stach
2016-07-11 10:25   ` Philipp Zabel
2016-06-17 10:13 ` [PATCH 3/5] drm/imx: imx-ldb: detach panel on unbind Lucas Stach
2016-06-20 12:03   ` Philipp Zabel
2016-06-17 10:13 ` [PATCH 4/5] drm/imx: drop deprecated load/unload drm_driver ops Lucas Stach
2016-06-17 12:48   ` Daniel Vetter
2016-06-24  7:46     ` Ying Liu
2016-06-17 10:13 ` [PATCH 5/5] drm/imx: don't destroy mode objects manually on driver unbind Lucas Stach
2016-06-20 12:00   ` Philipp Zabel
2016-06-17 12:45 ` [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Daniel Vetter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox