* [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
* 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
* [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
* 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
* [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
* 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 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
* [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 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 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
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