diff options
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index ae247eec87c0..292f73f0ddbd 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
| @@ -264,6 +264,8 @@ static void radeon_unpin_work_func(struct work_struct *__work) | |||
| 264 | radeon_bo_unreserve(work->old_rbo); | 264 | radeon_bo_unreserve(work->old_rbo); |
| 265 | } else | 265 | } else |
| 266 | DRM_ERROR("failed to reserve buffer after flip\n"); | 266 | DRM_ERROR("failed to reserve buffer after flip\n"); |
| 267 | |||
| 268 | drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); | ||
| 267 | kfree(work); | 269 | kfree(work); |
| 268 | } | 270 | } |
| 269 | 271 | ||
| @@ -371,6 +373,8 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc, | |||
| 371 | new_radeon_fb = to_radeon_framebuffer(fb); | 373 | new_radeon_fb = to_radeon_framebuffer(fb); |
| 372 | /* schedule unpin of the old buffer */ | 374 | /* schedule unpin of the old buffer */ |
| 373 | obj = old_radeon_fb->obj; | 375 | obj = old_radeon_fb->obj; |
| 376 | /* take a reference to the old object */ | ||
| 377 | drm_gem_object_reference(obj); | ||
| 374 | rbo = gem_to_radeon_bo(obj); | 378 | rbo = gem_to_radeon_bo(obj); |
| 375 | work->old_rbo = rbo; | 379 | work->old_rbo = rbo; |
| 376 | INIT_WORK(&work->work, radeon_unpin_work_func); | 380 | INIT_WORK(&work->work, radeon_unpin_work_func); |
| @@ -378,12 +382,9 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc, | |||
| 378 | /* We borrow the event spin lock for protecting unpin_work */ | 382 | /* We borrow the event spin lock for protecting unpin_work */ |
| 379 | spin_lock_irqsave(&dev->event_lock, flags); | 383 | spin_lock_irqsave(&dev->event_lock, flags); |
| 380 | if (radeon_crtc->unpin_work) { | 384 | if (radeon_crtc->unpin_work) { |
| 381 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 382 | kfree(work); | ||
| 383 | radeon_fence_unref(&fence); | ||
| 384 | |||
| 385 | DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); | 385 | DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); |
| 386 | return -EBUSY; | 386 | r = -EBUSY; |
| 387 | goto unlock_free; | ||
| 387 | } | 388 | } |
| 388 | radeon_crtc->unpin_work = work; | 389 | radeon_crtc->unpin_work = work; |
| 389 | radeon_crtc->deferred_flip_completion = 0; | 390 | radeon_crtc->deferred_flip_completion = 0; |
| @@ -497,6 +498,8 @@ pflip_cleanup1: | |||
| 497 | pflip_cleanup: | 498 | pflip_cleanup: |
| 498 | spin_lock_irqsave(&dev->event_lock, flags); | 499 | spin_lock_irqsave(&dev->event_lock, flags); |
| 499 | radeon_crtc->unpin_work = NULL; | 500 | radeon_crtc->unpin_work = NULL; |
| 501 | unlock_free: | ||
| 502 | drm_gem_object_unreference_unlocked(old_radeon_fb->obj); | ||
| 500 | spin_unlock_irqrestore(&dev->event_lock, flags); | 503 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 501 | radeon_fence_unref(&fence); | 504 | radeon_fence_unref(&fence); |
| 502 | kfree(work); | 505 | kfree(work); |
