瀏覽代碼

drm/armada: move overlay plane work out from under spinlock

Move the overlay plane work out from under the spinlock so that both the
primary and overlay planes run their work in the same context.  This is
necessary so that we can use frame works with the overlay plane.

However, we must update the CRTC registers under the spinlock, so fix up
the overlay code for that.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Russell King 8 年之前
父節點
當前提交
a3f6a18f9a
共有 2 個文件被更改,包括 5 次插入1 次删除
  1. 1 1
      drivers/gpu/drm/armada/armada_crtc.c
  2. 4 0
      drivers/gpu/drm/armada/armada_overlay.c

+ 1 - 1
drivers/gpu/drm/armada/armada_crtc.c

@@ -471,11 +471,11 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 	if (stat & VSYNC_IRQ)
 	if (stat & VSYNC_IRQ)
 		drm_crtc_handle_vblank(&dcrtc->crtc);
 		drm_crtc_handle_vblank(&dcrtc->crtc);
 
 
-	spin_lock(&dcrtc->irq_lock);
 	ovl_plane = dcrtc->plane;
 	ovl_plane = dcrtc->plane;
 	if (ovl_plane)
 	if (ovl_plane)
 		armada_drm_plane_work_run(dcrtc, ovl_plane);
 		armada_drm_plane_work_run(dcrtc, ovl_plane);
 
 
+	spin_lock(&dcrtc->irq_lock);
 	if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
 	if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
 		int i = stat & GRA_FRAME_IRQ0 ? 0 : 1;
 		int i = stat & GRA_FRAME_IRQ0 ? 0 : 1;
 		uint32_t val;
 		uint32_t val;

+ 4 - 0
drivers/gpu/drm/armada/armada_overlay.c

@@ -84,10 +84,14 @@ static void armada_ovl_plane_work(struct armada_crtc *dcrtc,
 {
 {
 	struct armada_ovl_plane *dplane = container_of(work->plane,
 	struct armada_ovl_plane *dplane = container_of(work->plane,
 					struct armada_ovl_plane, base.base);
 					struct armada_ovl_plane, base.base);
+	unsigned long flags;
 
 
 	trace_armada_ovl_plane_work(&dcrtc->crtc, work->plane);
 	trace_armada_ovl_plane_work(&dcrtc->crtc, work->plane);
 
 
+	spin_lock_irqsave(&dcrtc->irq_lock, flags);
 	armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
 	armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
+	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
+
 	armada_ovl_retire_fb(dplane, NULL);
 	armada_ovl_retire_fb(dplane, NULL);
 }
 }