Both the primary and overlay planes retire framebuffers in a similar manner; this can be consolidated by moving the retirement up to the armada_plane_work layer. Signed-off-by: Russell King <rmk+kernel@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/armada/armada_crtc.c | 12 +++++++----- drivers/gpu/drm/armada/armada_crtc.h | 1 + drivers/gpu/drm/armada/armada_overlay.c | 30 +++++------------------------- 3 files changed, 13 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index be3fd82ef516..d1f4171966cc 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -24,7 +24,6 @@ struct armada_frame_work { struct armada_plane_work work; struct drm_pending_vblank_event *event; struct armada_regs regs[4]; - struct drm_framebuffer *old_fb; }; enum csc_mode { @@ -221,11 +220,16 @@ static void armada_drm_plane_work_call(struct armada_crtc *dcrtc, void (*fn)(struct armada_crtc *, struct armada_plane_work *)) { struct armada_plane *dplane = drm_to_armada_plane(work->plane); + struct drm_framebuffer *fb = work->old_fb; if (fn) fn(dcrtc, work); drm_crtc_vblank_put(&dcrtc->crtc); + /* Finally, queue the process-half of the cleanup. */ + if (fb) + armada_drm_queue_unref_work(dcrtc->crtc.dev, fb); + wake_up(&dplane->frame_wait); } @@ -287,8 +291,6 @@ static void armada_drm_crtc_finish_frame_work(struct armada_crtc *dcrtc, spin_unlock_irqrestore(&dev->event_lock, flags); } - /* Finally, queue the process-half of the cleanup. */ - __armada_drm_queue_unref_work(dcrtc->crtc.dev, fwork->old_fb); kfree(fwork); } @@ -339,7 +341,7 @@ static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc, work = armada_drm_crtc_alloc_frame_work(dcrtc->crtc.primary); if (work) { - work->old_fb = fb; + work->work.old_fb = fb; if (armada_drm_plane_work_queue(dcrtc, &work->work) == 0) return; @@ -1031,7 +1033,7 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc, return -ENOMEM; work->event = event; - work->old_fb = dcrtc->crtc.primary->fb; + work->work.old_fb = dcrtc->crtc.primary->fb; i = armada_drm_crtc_calc_fb(fb, crtc->x, crtc->y, work->regs, dcrtc->interlaced); diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h index 521ae5b6ad86..b40db72c61d8 100644 --- a/drivers/gpu/drm/armada/armada_crtc.h +++ b/drivers/gpu/drm/armada/armada_crtc.h @@ -39,6 +39,7 @@ struct armada_plane_work { void (*fn)(struct armada_crtc *, struct armada_plane_work *); void (*cancel)(struct armada_crtc *, struct armada_plane_work *); struct drm_plane *plane; + struct drm_framebuffer *old_fb; }; struct armada_plane_state { diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index 04746ade74e6..01087c952916 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c @@ -32,7 +32,6 @@ struct armada_ovl_plane_properties { struct armada_ovl_plane { struct armada_plane base; - struct drm_framebuffer *old_fb; struct { struct armada_plane_work work; struct armada_regs regs[13]; @@ -67,17 +66,6 @@ armada_ovl_update_attr(struct armada_ovl_plane_properties *prop, spin_unlock_irq(&dcrtc->irq_lock); } -static void armada_ovl_retire_fb(struct armada_ovl_plane *dplane, - struct drm_framebuffer *fb) -{ - struct drm_framebuffer *old_fb; - - old_fb = xchg(&dplane->old_fb, fb); - - if (old_fb) - armada_drm_queue_unref_work(dplane->base.base.dev, old_fb); -} - /* === Plane support === */ static void armada_ovl_plane_work(struct armada_crtc *dcrtc, struct armada_plane_work *work) @@ -91,8 +79,6 @@ static void armada_ovl_plane_work(struct armada_crtc *dcrtc, spin_lock_irqsave(&dcrtc->irq_lock, flags); armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs); spin_unlock_irqrestore(&dcrtc->irq_lock, flags); - - armada_ovl_retire_fb(dplane, NULL); } static int @@ -196,8 +182,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, */ drm_framebuffer_get(fb); - if (plane->fb) - armada_ovl_retire_fb(dplane, plane->fb); + dplane->vbl.work.old_fb = plane->fb; dplane->base.state.src_y = src_y = src.y1 >> 16; dplane->base.state.src_x = src_x = src.x1 >> 16; @@ -223,6 +208,8 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, val = fb->pitches[1] << 16 | fb->pitches[2]; armada_reg_queue_set(dplane->vbl.regs, idx, val, LCD_SPU_DMA_PITCH_UV); + } else { + dplane->vbl.work.old_fb = NULL; } val = (drm_rect_height(&src) & 0xffff0000) | drm_rect_width(&src) >> 16; @@ -266,17 +253,10 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, static int armada_ovl_plane_disable(struct drm_plane *plane, struct drm_modeset_acquire_ctx *ctx) { - struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane); - struct drm_framebuffer *fb; - armada_drm_plane_disable(plane, ctx); - if (dplane->base.base.crtc) - drm_to_armada_crtc(dplane->base.base.crtc)->plane = NULL; - - fb = xchg(&dplane->old_fb, NULL); - if (fb) - drm_framebuffer_put(fb); + if (plane->crtc) + drm_to_armada_crtc(plane->crtc)->plane = NULL; return 0; } -- 2.7.4 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel