aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2014-01-02 04:19:54 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2014-01-09 08:17:25 -0500
commit80e4ed5411dddbafe90083a6c82dd87e88fde0d7 (patch)
tree90b2e37a5bb34c4742aec8b7b6c3bfbea0bcaa73
parentec72a81e27d735eb0b5f9325be3d88aa4cb5510a (diff)
drm/omap: fix: change dev_unload order
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> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index fca5667d3bf5..c57e99cc3caa 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)
517 DBG("unload: dev=%p", dev); 517 DBG("unload: dev=%p", dev);
518 518
519 drm_kms_helper_poll_fini(dev); 519 drm_kms_helper_poll_fini(dev);
520 drm_vblank_cleanup(dev);
521 omap_drm_irq_uninstall(dev);
522 520
523 omap_fbdev_free(dev); 521 omap_fbdev_free(dev);
524 omap_modeset_free(dev); 522 omap_modeset_free(dev);
525 omap_gem_deinit(dev); 523 omap_gem_deinit(dev);
526 524
527 flush_workqueue(priv->wq);
528 destroy_workqueue(priv->wq); 525 destroy_workqueue(priv->wq);
529 526
527 drm_vblank_cleanup(dev);
528 omap_drm_irq_uninstall(dev);
529
530 kfree(dev->dev_private); 530 kfree(dev->dev_private);
531 dev->dev_private = NULL; 531 dev->dev_private = NULL;
532 532