[PATCH v3 13/20] drm: omapdrm: Use a spinlock to protect the CRTC pending flag

2016-09-27 Thread Tomi Valkeinen
On 19/09/16 15:27, Laurent Pinchart wrote:
> The flag will need to be accessed atomically in the vblank interrupt
> handler, memory barriers won't be enough.
> 

Please write the descriptions so that they don't depend on the subject.

Reviewed-by: Tomi Valkeinen 

 Tomi

-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: 



[PATCH v3 13/20] drm: omapdrm: Use a spinlock to protect the CRTC pending flag

2016-09-19 Thread Laurent Pinchart
The flag will need to be accessed atomically in the vblank interrupt
handler, memory barriers won't be enough.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 28 +---
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 8fef6558197b..ac0ec851865c 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)
return omap_crtc->channel;
 }

+static bool omap_crtc_is_pending(struct drm_crtc *crtc)
+{
+   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+   unsigned long flags;
+   bool pending;
+
+   spin_lock_irqsave(>dev->event_lock, flags);
+   pending = omap_crtc->pending;
+   spin_unlock_irqrestore(>dev->event_lock, flags);
+
+   return pending;
+}
+
 int omap_crtc_wait_pending(struct drm_crtc *crtc)
 {
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
@@ -78,7 +91,7 @@ int omap_crtc_wait_pending(struct drm_crtc *crtc)
 * a single frame refresh even on slower displays.
 */
return wait_event_timeout(omap_crtc->pending_wait,
- !omap_crtc->pending,
+ !omap_crtc_is_pending(crtc),
  msecs_to_jiffies(250));
 }

@@ -297,6 +310,7 @@ static void omap_crtc_vblank_irq(struct omap_drm_irq *irq, 
uint32_t irqstatus)
struct omap_crtc *omap_crtc =
container_of(irq, struct omap_crtc, vblank_irq);
struct drm_device *dev = omap_crtc->base.dev;
+   struct drm_crtc *crtc = _crtc->base;

if (dispc_mgr_go_busy(omap_crtc->channel))
return;
@@ -305,10 +319,10 @@ static void omap_crtc_vblank_irq(struct omap_drm_irq 
*irq, uint32_t irqstatus)

__omap_irq_unregister(dev, _crtc->vblank_irq);

-   rmb();
+   spin_lock(>dev->event_lock);
WARN_ON(!omap_crtc->pending);
omap_crtc->pending = false;
-   wmb();
+   spin_unlock(>dev->event_lock);

/* wake up userspace */
omap_crtc_complete_page_flip(_crtc->base);
@@ -340,10 +354,10 @@ static void omap_crtc_enable(struct drm_crtc *crtc)

DBG("%s", omap_crtc->name);

-   rmb();
+   spin_lock_irq(>dev->event_lock);
WARN_ON(omap_crtc->pending);
omap_crtc->pending = true;
-   wmb();
+   spin_unlock_irq(>dev->event_lock);

omap_irq_register(crtc->dev, _crtc->vblank_irq);

@@ -449,10 +463,10 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,

DBG("%s: GO", omap_crtc->name);

-   rmb();
+   spin_lock_irq(>dev->event_lock);
WARN_ON(omap_crtc->pending);
omap_crtc->pending = true;
-   wmb();
+   spin_unlock_irq(>dev->event_lock);

dispc_mgr_go(omap_crtc->channel);
omap_irq_register(crtc->dev, _crtc->vblank_irq);
-- 
Regards,

Laurent Pinchart