summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm/omap_crtc.c
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2014-04-02 14:31:57 +0300
committerTomi Valkeinen <tomi.valkeinen@ti.com>2014-04-14 12:34:14 +0300
commite2f8fd74ec1bf15cb2abc1b11f7d9fa09581024e (patch)
tree020db67510226850520f26769da44549f46d050f /drivers/gpu/drm/omapdrm/omap_crtc.c
parentea7e3a662814447cd329390feddd04b9ec0a4b82 (diff)
drm/omap: fix race issue when unloading omapdrm
At module unload, omap_fbdev_free() gets called which releases the framebuffers. However, the framebuffers are still used by crtcs, and will be released only later at vsync. The driver doesn't wait for this, and goes on to release the rest of the resources, which often causes a crash. This patchs adds a omap_crtc_flush() function which waits until the crtc has finished with its apply queue and page flips. The function utilizes a simple polling while-loop, as the performance is not an issue here. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Reviewed-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_crtc.c')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 0acbe62901d..161a74a3ac5 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -621,6 +621,25 @@ static void omap_crtc_post_apply(struct omap_drm_apply *apply)
/* nothing needed for post-apply */
}
+void omap_crtc_flush(struct drm_crtc *crtc)
+{
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+ int loops = 0;
+
+ while (!list_empty(&omap_crtc->pending_applies) ||
+ !list_empty(&omap_crtc->queued_applies) ||
+ omap_crtc->event || omap_crtc->old_fb) {
+
+ if (++loops > 10) {
+ dev_err(crtc->dev->dev,
+ "omap_crtc_flush() timeout\n");
+ break;
+ }
+
+ schedule_timeout_uninterruptible(msecs_to_jiffies(20));
+ }
+}
+
static const char *channel_names[] = {
[OMAP_DSS_CHANNEL_LCD] = "lcd",
[OMAP_DSS_CHANNEL_DIGIT] = "tv",