aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_atomic.c
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2015-08-31 06:25:04 -0400
committerJani Nikula <jani.nikula@intel.com>2015-09-01 04:57:06 -0400
commitc4749c9a4a9ddc16200ce46a19078357727bf4b1 (patch)
treed5496cf9517b7eea1ca822c2a14db8da8ec9fa6f /drivers/gpu/drm/drm_atomic.c
parent879a37d00f1882b1e56a66e626af4194d592d257 (diff)
drm/atomic: Fix bookkeeping with TEST_ONLY, v3.
Commit ec9f932ed41622d120de52a5b525e4d77b9ef17e "drm/atomic: Cleanup on error properly in the atomic ioctl." cleaned up some error paths, but didn't fix the TEST_ONLY path. In the check only case plane->fb shouldn't be updated, and the vblank events should be cleared as on failure. Changes since v1: - Fix -EDEADLK handling of vblank events too. - Free state last with CHECK_ONLY. Changes since v2: - Add comment about freeing crtc_state->event with TEST_ONLY. (Daniel Stone) Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Diffstat (limited to 'drivers/gpu/drm/drm_atomic.c')
-rw-r--r--drivers/gpu/drm/drm_atomic.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 434915448ea0..f7d5166f89b2 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1515,7 +1515,8 @@ retry:
1515 copied_props++; 1515 copied_props++;
1516 } 1516 }
1517 1517
1518 if (obj->type == DRM_MODE_OBJECT_PLANE && count_props) { 1518 if (obj->type == DRM_MODE_OBJECT_PLANE && count_props &&
1519 !(arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)) {
1519 plane = obj_to_plane(obj); 1520 plane = obj_to_plane(obj);
1520 plane_mask |= (1 << drm_plane_index(plane)); 1521 plane_mask |= (1 << drm_plane_index(plane));
1521 plane->old_fb = plane->fb; 1522 plane->old_fb = plane->fb;
@@ -1537,10 +1538,11 @@ retry:
1537 } 1538 }
1538 1539
1539 if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) { 1540 if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) {
1541 /*
1542 * Unlike commit, check_only does not clean up state.
1543 * Below we call drm_atomic_state_free for it.
1544 */
1540 ret = drm_atomic_check_only(state); 1545 ret = drm_atomic_check_only(state);
1541 /* _check_only() does not free state, unlike _commit() */
1542 if (!ret)
1543 drm_atomic_state_free(state);
1544 } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) { 1546 } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
1545 ret = drm_atomic_async_commit(state); 1547 ret = drm_atomic_async_commit(state);
1546 } else { 1548 } else {
@@ -1567,25 +1569,30 @@ out:
1567 plane->old_fb = NULL; 1569 plane->old_fb = NULL;
1568 } 1570 }
1569 1571
1572 if (ret && arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
1573 /*
1574 * TEST_ONLY and PAGE_FLIP_EVENT are mutually exclusive,
1575 * if they weren't, this code should be called on success
1576 * for TEST_ONLY too.
1577 */
1578
1579 for_each_crtc_in_state(state, crtc, crtc_state, i) {
1580 if (!crtc_state->event)
1581 continue;
1582
1583 destroy_vblank_event(dev, file_priv,
1584 crtc_state->event);
1585 }
1586 }
1587
1570 if (ret == -EDEADLK) { 1588 if (ret == -EDEADLK) {
1571 drm_atomic_state_clear(state); 1589 drm_atomic_state_clear(state);
1572 drm_modeset_backoff(&ctx); 1590 drm_modeset_backoff(&ctx);
1573 goto retry; 1591 goto retry;
1574 } 1592 }
1575 1593
1576 if (ret) { 1594 if (ret || arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)
1577 if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
1578 for_each_crtc_in_state(state, crtc, crtc_state, i) {
1579 if (!crtc_state->event)
1580 continue;
1581
1582 destroy_vblank_event(dev, file_priv,
1583 crtc_state->event);
1584 }
1585 }
1586
1587 drm_atomic_state_free(state); 1595 drm_atomic_state_free(state);
1588 }
1589 1596
1590 drm_modeset_drop_locks(&ctx); 1597 drm_modeset_drop_locks(&ctx);
1591 drm_modeset_acquire_fini(&ctx); 1598 drm_modeset_acquire_fini(&ctx);