diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2019-08-03 06:04:23 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2019-08-03 06:04:23 -0700 |
| commit | a417d8a74685871a4df25dcb05c89267ea2852af (patch) | |
| tree | 46c316fa3a087c7892af30629abaf5920ee20725 /drivers/gpu | |
| parent | aa2bb48a420ba0219eea32a11bae3192348e95a2 (diff) | |
| parent | 9c2892993d553480e694eb7d7fa2cc11ec371620 (diff) | |
Merge "drm/msm: fix re-entry problem for msm_atomic_commit"
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_atomic.c | 24 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_drv.h | 3 |
2 files changed, 19 insertions, 8 deletions
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 99f89841a74a..8467be8c3f0b 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (C) 2014 Red Hat * Author: Rob Clark <robdclark@gmail.com> * @@ -27,22 +27,26 @@ struct msm_commit { uint32_t fence; struct msm_fence_cb fence_cb; uint32_t crtc_mask; + uint32_t plane_mask; struct kthread_work commit_work; }; /* block until specified crtcs are no longer pending update, and * atomically mark them as pending update */ -static int start_atomic(struct msm_drm_private *priv, uint32_t crtc_mask) +static int start_atomic(struct msm_drm_private *priv, uint32_t crtc_mask, + uint32_t plane_mask) { int ret; spin_lock(&priv->pending_crtcs_event.lock); ret = wait_event_interruptible_locked(priv->pending_crtcs_event, - !(priv->pending_crtcs & crtc_mask)); + !(priv->pending_crtcs & crtc_mask) && + !(priv->pending_planes & plane_mask)); if (ret == 0) { DBG("start: %08x", crtc_mask); priv->pending_crtcs |= crtc_mask; + priv->pending_planes |= plane_mask; } spin_unlock(&priv->pending_crtcs_event.lock); @@ -51,18 +55,21 @@ static int start_atomic(struct msm_drm_private *priv, uint32_t crtc_mask) /* clear specified crtcs (no longer pending update) */ -static void end_atomic(struct msm_drm_private *priv, uint32_t crtc_mask) +static void end_atomic(struct msm_drm_private *priv, uint32_t crtc_mask, + uint32_t plane_mask) { spin_lock(&priv->pending_crtcs_event.lock); DBG("end: %08x", crtc_mask); priv->pending_crtcs &= ~crtc_mask; + priv->pending_planes &= ~plane_mask; wake_up_all_locked(&priv->pending_crtcs_event); spin_unlock(&priv->pending_crtcs_event.lock); } static void commit_destroy(struct msm_commit *commit) { - end_atomic(commit->dev->dev_private, commit->crtc_mask); + end_atomic(commit->dev->dev_private, commit->crtc_mask, + commit->plane_mask); kfree(commit); } @@ -593,7 +600,7 @@ int msm_atomic_commit(struct drm_device *dev, struct drm_crtc *crtc = state->crtcs[i]; if (!crtc) continue; - commit->crtc_mask |= (1 << drm_crtc_index(crtc)); + commit->crtc_mask |= (1 << i); } /* @@ -608,13 +615,16 @@ int msm_atomic_commit(struct drm_device *dev, if ((plane->state->fb != new_state->fb) && new_state->fb) commit_set_fence(commit, new_state->fb); + + commit->plane_mask |= (1 << i); } /* * Wait for pending updates on any of the same crtc's and then * mark our set of crtc's as busy: */ - ret = start_atomic(dev->dev_private, commit->crtc_mask); + ret = start_atomic(dev->dev_private, commit->crtc_mask, + commit->plane_mask); if (ret) { DRM_ERROR("start_atomic failed: %d\n", ret); commit_destroy(commit); diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 87649f7ec3dd..a9c28feb11ce 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark <robdclark@gmail.com> * @@ -319,6 +319,7 @@ struct msm_drm_private { /* crtcs pending async atomic updates: */ uint32_t pending_crtcs; + uint32_t pending_planes; wait_queue_head_t pending_crtcs_event; /* Registered address spaces.. currently this is fixed per # of |
