From ffe881fba1e8467872fcb926fe2817aedbec2592 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 24 May 2017 16:51:54 +0200 Subject: [PATCH 1/3] drm/fsl: Drop drm_vblank_cleanup Again cleanup before irq disabling doesn't really stop the races, so just drop it. Proper fix would be to put drm_atomic_helper_shutdown before everything gets cleaned up. Cc: Stefan Agner Signed-off-by: Daniel Vetter Signed-off-by: Stefan Agner --- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index 6e00f4b267f1..b34d09b59eee 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -109,7 +109,6 @@ done: drm_fbdev_cma_fini(fsl_dev->fbdev); drm_mode_config_cleanup(dev); - drm_vblank_cleanup(dev); drm_irq_uninstall(dev); dev->dev_private = NULL; @@ -127,7 +126,6 @@ static void fsl_dcu_unload(struct drm_device *dev) drm_fbdev_cma_fini(fsl_dev->fbdev); drm_mode_config_cleanup(dev); - drm_vblank_cleanup(dev); drm_irq_uninstall(dev); dev->dev_private = NULL; From 685ec6ebcd0edde718d2c95a550bca36563c9055 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 1 Jun 2017 19:43:30 -0700 Subject: [PATCH 2/3] drm/fsl-dcu: implement irq_preinstall/uninstall callbacks Make use of the irq_preinstall/uninstall callback to clear and mask all interrupts. Use write 1 to clear as documented by the data sheet (writing a 0 seems to have cleared interrupt status too). Remove fsl_dcu_drm_irq_init and call drm_irq_install directly from fsl_dcu_load makes error handling a bit simpler. Do not set irq_enabled since drm_irq_install is taking care of it. Signed-off-by: Stefan Agner --- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index b34d09b59eee..b134acf19c41 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -51,19 +51,12 @@ static const struct regmap_config fsl_dcu_regmap_config = { .volatile_reg = fsl_dcu_drm_is_volatile_reg, }; -static int fsl_dcu_drm_irq_init(struct drm_device *dev) +static void fsl_dcu_irq_uninstall(struct drm_device *dev) { struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; - int ret; - ret = drm_irq_install(dev, fsl_dev->irq); - if (ret < 0) - dev_err(dev->dev, "failed to install IRQ handler\n"); - - regmap_write(fsl_dev->regmap, DCU_INT_STATUS, 0); + regmap_write(fsl_dev->regmap, DCU_INT_STATUS, ~0); regmap_write(fsl_dev->regmap, DCU_INT_MASK, ~0); - - return ret; } static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) @@ -83,10 +76,11 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) goto done; } - ret = fsl_dcu_drm_irq_init(dev); - if (ret < 0) + ret = drm_irq_install(dev, fsl_dev->irq); + if (ret < 0) { + dev_err(dev->dev, "failed to install IRQ handler\n"); goto done; - dev->irq_enabled = true; + } if (legacyfb_depth != 16 && legacyfb_depth != 24 && legacyfb_depth != 32) { @@ -168,6 +162,8 @@ static struct drm_driver fsl_dcu_drm_driver = { .load = fsl_dcu_load, .unload = fsl_dcu_unload, .irq_handler = fsl_dcu_drm_irq, + .irq_preinstall = fsl_dcu_irq_uninstall, + .irq_uninstall = fsl_dcu_irq_uninstall, .gem_free_object_unlocked = drm_gem_cma_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, From 09cedcb6d4c585336c5a75cbbb3a5addf710b03e Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 1 Jun 2017 19:50:21 -0700 Subject: [PATCH 3/3] drm/fsl-dcu: use new drm_atomic_helper_shutdown Commit 18dddadc78c9 ("drm/atomic: Introduce drm_atomic_helper_shutdown") introduced a new helper to shutdown all CRTCs to replace the buggy drm_crtc_force_disable_all() function. Make use of the new atomic helper drm_atomic_helper_shutdown() to shutdown CRTCs. Signed-off-by: Stefan Agner --- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index b134acf19c41..5cbde196895a 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -113,7 +113,7 @@ static void fsl_dcu_unload(struct drm_device *dev) { struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; - drm_crtc_force_disable_all(dev); + drm_atomic_helper_shutdown(dev); drm_kms_helper_poll_fini(dev); if (fsl_dev->fbdev)