From: Russell King Date: Fri, 7 Jul 2017 15:56:20 +0100 Subject: drm/armada: add work cancel callback Git-commit: 2839d45c7d92a521364347dbd023d218a5913e26 Patch-mainline: v4.16-rc1 References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166 Add a work cancel callback, so that work items can add functionality to clean themselves up when they are cancelled. Signed-off-by: Russell King Acked-by: Petr Tesarik --- drivers/gpu/drm/armada/armada_crtc.c | 23 ++++++++++++++++------- drivers/gpu/drm/armada/armada_crtc.h | 1 + 2 files changed, 17 insertions(+), 7 deletions(-) --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -216,6 +216,19 @@ static unsigned armada_drm_crtc_calc_fb( return i; } +static void armada_drm_plane_work_call(struct armada_crtc *dcrtc, + struct armada_plane_work *work, + void (*fn)(struct armada_crtc *, struct armada_plane_work *)) +{ + struct armada_plane *dplane = drm_to_armada_plane(work->plane); + + if (fn) + fn(dcrtc, work); + drm_crtc_vblank_put(&dcrtc->crtc); + + wake_up(&dplane->frame_wait); +} + static void armada_drm_plane_work_run(struct armada_crtc *dcrtc, struct drm_plane *plane) { @@ -223,12 +236,8 @@ static void armada_drm_plane_work_run(st struct armada_plane_work *work = xchg(&dplane->work, NULL); /* Handle any pending frame work. */ - if (work) { - work->fn(dcrtc, work); - drm_crtc_vblank_put(&dcrtc->crtc); - } - - wake_up(&dplane->frame_wait); + if (work) + armada_drm_plane_work_call(dcrtc, work, work->fn); } int armada_drm_plane_work_queue(struct armada_crtc *dcrtc, @@ -261,7 +270,7 @@ void armada_drm_plane_work_cancel(struct struct armada_plane_work *work = xchg(&dplane->work, NULL); if (work) - drm_crtc_vblank_put(&dcrtc->crtc); + armada_drm_plane_work_call(dcrtc, work, work->cancel); } static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc, --- a/drivers/gpu/drm/armada/armada_crtc.h +++ b/drivers/gpu/drm/armada/armada_crtc.h @@ -37,6 +37,7 @@ struct armada_variant; 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; };