diff options
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_crtc.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 7b67ecb02b74..827ac46a6d5e 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c | |||
@@ -69,6 +69,19 @@ enum omap_channel omap_crtc_channel(struct drm_crtc *crtc) | |||
69 | return omap_crtc->channel; | 69 | return omap_crtc->channel; |
70 | } | 70 | } |
71 | 71 | ||
72 | static bool omap_crtc_is_pending(struct drm_crtc *crtc) | ||
73 | { | ||
74 | struct omap_crtc *omap_crtc = to_omap_crtc(crtc); | ||
75 | unsigned long flags; | ||
76 | bool pending; | ||
77 | |||
78 | spin_lock_irqsave(&crtc->dev->event_lock, flags); | ||
79 | pending = omap_crtc->pending; | ||
80 | spin_unlock_irqrestore(&crtc->dev->event_lock, flags); | ||
81 | |||
82 | return pending; | ||
83 | } | ||
84 | |||
72 | int omap_crtc_wait_pending(struct drm_crtc *crtc) | 85 | int omap_crtc_wait_pending(struct drm_crtc *crtc) |
73 | { | 86 | { |
74 | struct omap_crtc *omap_crtc = to_omap_crtc(crtc); | 87 | struct omap_crtc *omap_crtc = to_omap_crtc(crtc); |
@@ -78,7 +91,7 @@ int omap_crtc_wait_pending(struct drm_crtc *crtc) | |||
78 | * a single frame refresh even on slower displays. | 91 | * a single frame refresh even on slower displays. |
79 | */ | 92 | */ |
80 | return wait_event_timeout(omap_crtc->pending_wait, | 93 | return wait_event_timeout(omap_crtc->pending_wait, |
81 | !omap_crtc->pending, | 94 | !omap_crtc_is_pending(crtc), |
82 | msecs_to_jiffies(250)); | 95 | msecs_to_jiffies(250)); |
83 | } | 96 | } |
84 | 97 | ||
@@ -296,6 +309,7 @@ static void omap_crtc_vblank_irq(struct omap_drm_irq *irq, uint32_t irqstatus) | |||
296 | struct omap_crtc *omap_crtc = | 309 | struct omap_crtc *omap_crtc = |
297 | container_of(irq, struct omap_crtc, vblank_irq); | 310 | container_of(irq, struct omap_crtc, vblank_irq); |
298 | struct drm_device *dev = omap_crtc->base.dev; | 311 | struct drm_device *dev = omap_crtc->base.dev; |
312 | struct drm_crtc *crtc = &omap_crtc->base; | ||
299 | 313 | ||
300 | if (dispc_mgr_go_busy(omap_crtc->channel)) | 314 | if (dispc_mgr_go_busy(omap_crtc->channel)) |
301 | return; | 315 | return; |
@@ -304,10 +318,10 @@ static void omap_crtc_vblank_irq(struct omap_drm_irq *irq, uint32_t irqstatus) | |||
304 | 318 | ||
305 | __omap_irq_unregister(dev, &omap_crtc->vblank_irq); | 319 | __omap_irq_unregister(dev, &omap_crtc->vblank_irq); |
306 | 320 | ||
307 | rmb(); | 321 | spin_lock(&crtc->dev->event_lock); |
308 | WARN_ON(!omap_crtc->pending); | 322 | WARN_ON(!omap_crtc->pending); |
309 | omap_crtc->pending = false; | 323 | omap_crtc->pending = false; |
310 | wmb(); | 324 | spin_unlock(&crtc->dev->event_lock); |
311 | 325 | ||
312 | /* wake up userspace */ | 326 | /* wake up userspace */ |
313 | omap_crtc_complete_page_flip(&omap_crtc->base); | 327 | omap_crtc_complete_page_flip(&omap_crtc->base); |
@@ -339,10 +353,10 @@ static void omap_crtc_enable(struct drm_crtc *crtc) | |||
339 | 353 | ||
340 | DBG("%s", omap_crtc->name); | 354 | DBG("%s", omap_crtc->name); |
341 | 355 | ||
342 | rmb(); | 356 | spin_lock_irq(&crtc->dev->event_lock); |
343 | WARN_ON(omap_crtc->pending); | 357 | WARN_ON(omap_crtc->pending); |
344 | omap_crtc->pending = true; | 358 | omap_crtc->pending = true; |
345 | wmb(); | 359 | spin_unlock_irq(&crtc->dev->event_lock); |
346 | 360 | ||
347 | omap_irq_register(crtc->dev, &omap_crtc->vblank_irq); | 361 | omap_irq_register(crtc->dev, &omap_crtc->vblank_irq); |
348 | 362 | ||
@@ -427,16 +441,13 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc, | |||
427 | 441 | ||
428 | DBG("%s: GO", omap_crtc->name); | 442 | DBG("%s: GO", omap_crtc->name); |
429 | 443 | ||
430 | rmb(); | 444 | spin_lock_irq(&crtc->dev->event_lock); |
431 | WARN_ON(omap_crtc->pending); | 445 | WARN_ON(omap_crtc->pending); |
432 | omap_crtc->pending = true; | 446 | omap_crtc->pending = true; |
433 | wmb(); | ||
434 | 447 | ||
435 | if (crtc->state->event) { | 448 | if (crtc->state->event) |
436 | spin_lock_irq(&crtc->dev->event_lock); | ||
437 | omap_crtc->event = crtc->state->event; | 449 | omap_crtc->event = crtc->state->event; |
438 | spin_unlock_irq(&crtc->dev->event_lock); | 450 | spin_unlock_irq(&crtc->dev->event_lock); |
439 | } | ||
440 | 451 | ||
441 | dispc_mgr_go(omap_crtc->channel); | 452 | dispc_mgr_go(omap_crtc->channel); |
442 | omap_irq_register(crtc->dev, &omap_crtc->vblank_irq); | 453 | omap_irq_register(crtc->dev, &omap_crtc->vblank_irq); |