diff options
| author | Archit Taneja <archit@ti.com> | 2014-01-02 04:19:54 -0500 |
|---|---|---|
| committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-01-09 08:17:25 -0500 |
| commit | 80e4ed5411dddbafe90083a6c82dd87e88fde0d7 (patch) | |
| tree | 90b2e37a5bb34c4742aec8b7b6c3bfbea0bcaa73 | |
| parent | ec72a81e27d735eb0b5f9325be3d88aa4cb5510a (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.c | 6 |
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 | ||
