aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2013-02-22 09:53:38 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-03-03 13:51:33 -0500
commit4a35f83b2b7c6aae3fc0d1c4554fdc99dc33ad07 (patch)
tree82bd8df4e7b0719c38ca722b358d6e83922bd607 /drivers/gpu
parentb18ac466956c7e7b5abf7a2d6adf8c626267d0ae (diff)
drm/i915: Don't clobber crtc->fb when queue_flip fails
Restore crtc->fb to the old framebuffer if queue_flip fails. While at it, kill the pointless intel_fb temp variable. v2: Update crtc->fb before queue_flip and restore it back after a failure. Cc: stable@vger.kernel.org Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Reported-and-Tested-by: Mika Kuoppala <mika.kuoppala@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c11
1 files changed, 4 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0ff10b3af9ea..09659ff6d24d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7264,8 +7264,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
7264{ 7264{
7265 struct drm_device *dev = crtc->dev; 7265 struct drm_device *dev = crtc->dev;
7266 struct drm_i915_private *dev_priv = dev->dev_private; 7266 struct drm_i915_private *dev_priv = dev->dev_private;
7267 struct intel_framebuffer *intel_fb; 7267 struct drm_framebuffer *old_fb = crtc->fb;
7268 struct drm_i915_gem_object *obj; 7268 struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj;
7269 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 7269 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
7270 struct intel_unpin_work *work; 7270 struct intel_unpin_work *work;
7271 unsigned long flags; 7271 unsigned long flags;
@@ -7290,8 +7290,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
7290 7290
7291 work->event = event; 7291 work->event = event;
7292 work->crtc = crtc; 7292 work->crtc = crtc;
7293 intel_fb = to_intel_framebuffer(crtc->fb); 7293 work->old_fb_obj = to_intel_framebuffer(old_fb)->obj;
7294 work->old_fb_obj = intel_fb->obj;
7295 INIT_WORK(&work->work, intel_unpin_work_fn); 7294 INIT_WORK(&work->work, intel_unpin_work_fn);
7296 7295
7297 ret = drm_vblank_get(dev, intel_crtc->pipe); 7296 ret = drm_vblank_get(dev, intel_crtc->pipe);
@@ -7311,9 +7310,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
7311 intel_crtc->unpin_work = work; 7310 intel_crtc->unpin_work = work;
7312 spin_unlock_irqrestore(&dev->event_lock, flags); 7311 spin_unlock_irqrestore(&dev->event_lock, flags);
7313 7312
7314 intel_fb = to_intel_framebuffer(fb);
7315 obj = intel_fb->obj;
7316
7317 if (atomic_read(&intel_crtc->unpin_work_count) >= 2) 7313 if (atomic_read(&intel_crtc->unpin_work_count) >= 2)
7318 flush_workqueue(dev_priv->wq); 7314 flush_workqueue(dev_priv->wq);
7319 7315
@@ -7348,6 +7344,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
7348 7344
7349cleanup_pending: 7345cleanup_pending:
7350 atomic_dec(&intel_crtc->unpin_work_count); 7346 atomic_dec(&intel_crtc->unpin_work_count);
7347 crtc->fb = old_fb;
7351 drm_gem_object_unreference(&work->old_fb_obj->base); 7348 drm_gem_object_unreference(&work->old_fb_obj->base);
7352 drm_gem_object_unreference(&obj->base); 7349 drm_gem_object_unreference(&obj->base);
7353 mutex_unlock(&dev->struct_mutex); 7350 mutex_unlock(&dev->struct_mutex);