@@ -1009,7 +1009,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
struct drm_mode_crtc_page_flip_target *page_flip = data;
struct drm_crtc *crtc;
struct drm_plane *plane;
- struct drm_framebuffer *fb = NULL, *old_fb;
+ struct drm_framebuffer *fb, *old_fb;
struct drm_pending_vblank_event *e = NULL;
u32 target_vblank = page_flip->sequence;
struct drm_modeset_acquire_ctx ctx;
@@ -1055,16 +1055,16 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
DRM_DEBUG("Invalid absolute flip target %u, "
"must be <= %u\n", target_vblank,
current_vblank + 1);
- drm_crtc_vblank_put(crtc);
- return -EINVAL;
+ ret = -EINVAL;
+ goto put_vblank;
}
break;
case DRM_MODE_PAGE_FLIP_TARGET_RELATIVE:
if (target_vblank != 0 && target_vblank != 1) {
DRM_DEBUG("Invalid relative flip target %u, "
"must be 0 or 1\n", target_vblank);
- drm_crtc_vblank_put(crtc);
- return -EINVAL;
+ ret = -EINVAL;
+ goto put_vblank;
}
target_vblank += current_vblank;
break;
@@ -1075,7 +1075,14 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
}
} else if (crtc->funcs->page_flip == NULL ||
(page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET)) {
- return -EINVAL;
+ ret = -EINVAL;
+ goto put_vblank;
+ }
+
+ fb = drm_framebuffer_lookup(dev, file_priv, page_flip->fb_id);
+ if (!fb) {
+ ret = -ENOENT;
+ goto put_vblank;
}
drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
@@ -1101,12 +1108,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
goto out;
}
- fb = drm_framebuffer_lookup(dev, file_priv, page_flip->fb_id);
- if (!fb) {
- ret = -ENOENT;
- goto out;
- }
-
if (plane->state) {
const struct drm_plane_state *state = plane->state;
@@ -1170,8 +1171,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
}
out:
- if (fb)
- drm_framebuffer_put(fb);
if (plane->old_fb)
drm_framebuffer_put(plane->old_fb);
plane->old_fb = NULL;
@@ -1185,6 +1184,8 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
+ drm_framebuffer_put(fb);
+put_vblank:
if (ret && crtc->funcs->page_flip_target)
drm_crtc_vblank_put(crtc);