From 37d86a4d83383dbd41a52826c004efc5c8acf453 Mon Sep 17 00:00:00 2001 From: Yashwanth Date: Tue, 21 Apr 2020 12:25:23 +0530 Subject: [PATCH] disp: msm: queue vblank work on disp thread during modeset If vblank work is queued to event thread, during modeset, there might be a case where vblank is enabled in between resulting in vblank ref count mismatch. This change queues vblank request to disp thread during modeset. Change-Id: I98b87b4209e1f7f535980eef22a50df17c346c23 Signed-off-by: Yashwanth --- msm/msm_drv.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/msm/msm_drv.c b/msm/msm_drv.c index 91bc4f5dde..a59fbdcb75 100644 --- a/msm/msm_drv.c +++ b/msm/msm_drv.c @@ -349,6 +349,8 @@ static int vblank_ctrl_queue_work(struct msm_drm_private *priv, int crtc_id, bool enable) { struct vblank_work *cur_work; + struct drm_crtc *crtc; + struct kthread_worker *worker; if (!priv || crtc_id >= priv->num_crtcs) return -EINVAL; @@ -357,14 +359,23 @@ static int vblank_ctrl_queue_work(struct msm_drm_private *priv, if (!cur_work) return -ENOMEM; + crtc = priv->crtcs[crtc_id]; + kthread_init_work(&cur_work->work, vblank_ctrl_worker); cur_work->crtc_id = crtc_id; cur_work->enable = enable; cur_work->priv = priv; - kthread_queue_work(&priv->event_thread[crtc_id].worker, - &cur_work->work); + /* During modeset scenario, vblank request is queued to + * display thread to avoid enabling irq resulting in + * vblank refcount mismatch + */ + if (crtc->state && drm_atomic_crtc_needs_modeset(crtc->state)) + worker = &priv->disp_thread[crtc_id].worker; + else + worker = &priv->event_thread[crtc_id].worker; + kthread_queue_work(worker, &cur_work->work); return 0; }