The current dev_unload order uninits the irqs too early.
In the current sequence, it's possible that a crtc queues work(apply_worker) to display a buffer, which registers to omap_crtc_apply_irq to notfiy the completion of the configuration we applied.
Calling drm_vblank_cleanup and omap_drm_irq_uninstall here causes the crtc's apply handler to never get called, which results in an incorrect state of the apply_irq.registered parameter.
This condition occurs where there is no mode set via omapdrm, and dev_lastclose tries to set a default fb mode via drm_fb_helper_restore_fbdev_mode. The apply work scheduled by restore_fbdev_mode is very close in time to the disabling of the irq handler, and hence leads to a race condition. We move the irq cleanup at the end of the unload sequence to prevent this.
Also, the call to flush_workqueue is removed since it's called internally by destroy_workqueue.
Signed-off-by: Archit Taneja archit@ti.com --- drivers/gpu/drm/omapdrm/omap_drv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index fca5667..c57e99c 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -517,16 +517,16 @@ static int dev_unload(struct drm_device *dev) DBG("unload: dev=%p", dev);
drm_kms_helper_poll_fini(dev); - drm_vblank_cleanup(dev); - omap_drm_irq_uninstall(dev);
omap_fbdev_free(dev); omap_modeset_free(dev); omap_gem_deinit(dev);
- flush_workqueue(priv->wq); destroy_workqueue(priv->wq);
+ drm_vblank_cleanup(dev); + omap_drm_irq_uninstall(dev); + kfree(dev->dev_private); dev->dev_private = NULL;