diff options
author | Rob Clark <robdclark@gmail.com> | 2013-09-11 17:14:30 -0400 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2013-09-11 17:37:48 -0400 |
commit | 6b8819c811c2a80a7e5896b4d1e2580be825d590 (patch) | |
tree | c2edc9c4c5e9ee2a19e1f0a124d72245b6c3369d /drivers/gpu | |
parent | f816f272437f3a2be0c9254d4ab8f917950d86a0 (diff) |
drm/msm: workaround for missing irq
Occasionally we seem to miss an IRQ from the ME (microengine). I'm not
entirely sure the root cause, but for now we can unwedge things by
retiring from the hangcheck timer.
Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/msm/msm_gpu.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 10cc4432416..7ddcfbebb1f 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -230,6 +230,8 @@ static void hangcheck_timer_reset(struct msm_gpu *gpu) static void hangcheck_handler(unsigned long data) { struct msm_gpu *gpu = (struct msm_gpu *)data; + struct drm_device *dev = gpu->dev; + struct msm_drm_private *priv = dev->dev_private; uint32_t fence = gpu->funcs->last_fence(gpu); if (fence != gpu->hangcheck_fence) { @@ -237,8 +239,6 @@ static void hangcheck_handler(unsigned long data) gpu->hangcheck_fence = fence; } else if (fence < gpu->submitted_fence) { /* no progress and not done.. hung! */ - struct drm_device *dev = gpu->dev; - struct msm_drm_private *priv = dev->dev_private; gpu->hangcheck_fence = fence; dev_err(dev->dev, "%s: hangcheck detected gpu lockup!\n", gpu->name); @@ -252,6 +252,9 @@ static void hangcheck_handler(unsigned long data) /* if still more pending work, reset the hangcheck timer: */ if (gpu->submitted_fence > gpu->hangcheck_fence) hangcheck_timer_reset(gpu); + + /* workaround for missing irq: */ + queue_work(priv->wq, &gpu->retire_work); } /* |