diff options
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 685bf146a482..3553d8232649 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -447,7 +447,8 @@ int drm_mode_getcrtc(struct drm_device *dev, | |||
447 | return 0; | 447 | return 0; |
448 | } | 448 | } |
449 | 449 | ||
450 | static int __drm_mode_set_config_internal(struct drm_mode_set *set) | 450 | static int __drm_mode_set_config_internal(struct drm_mode_set *set, |
451 | struct drm_modeset_acquire_ctx *ctx) | ||
451 | { | 452 | { |
452 | struct drm_crtc *crtc = set->crtc; | 453 | struct drm_crtc *crtc = set->crtc; |
453 | struct drm_framebuffer *fb; | 454 | struct drm_framebuffer *fb; |
@@ -497,7 +498,7 @@ int drm_mode_set_config_internal(struct drm_mode_set *set) | |||
497 | { | 498 | { |
498 | WARN_ON(drm_drv_uses_atomic_modeset(set->crtc->dev)); | 499 | WARN_ON(drm_drv_uses_atomic_modeset(set->crtc->dev)); |
499 | 500 | ||
500 | return __drm_mode_set_config_internal(set); | 501 | return __drm_mode_set_config_internal(set, NULL); |
501 | } | 502 | } |
502 | EXPORT_SYMBOL(drm_mode_set_config_internal); | 503 | EXPORT_SYMBOL(drm_mode_set_config_internal); |
503 | 504 | ||
@@ -554,6 +555,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, | |||
554 | struct drm_display_mode *mode = NULL; | 555 | struct drm_display_mode *mode = NULL; |
555 | struct drm_mode_set set; | 556 | struct drm_mode_set set; |
556 | uint32_t __user *set_connectors_ptr; | 557 | uint32_t __user *set_connectors_ptr; |
558 | struct drm_modeset_acquire_ctx ctx; | ||
557 | int ret; | 559 | int ret; |
558 | int i; | 560 | int i; |
559 | 561 | ||
@@ -567,15 +569,19 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, | |||
567 | if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000) | 569 | if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000) |
568 | return -ERANGE; | 570 | return -ERANGE; |
569 | 571 | ||
570 | drm_modeset_lock_all(dev); | ||
571 | crtc = drm_crtc_find(dev, crtc_req->crtc_id); | 572 | crtc = drm_crtc_find(dev, crtc_req->crtc_id); |
572 | if (!crtc) { | 573 | if (!crtc) { |
573 | DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id); | 574 | DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id); |
574 | ret = -ENOENT; | 575 | return -ENOENT; |
575 | goto out; | ||
576 | } | 576 | } |
577 | DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name); | 577 | DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name); |
578 | 578 | ||
579 | drm_modeset_acquire_init(&ctx, 0); | ||
580 | retry: | ||
581 | ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx); | ||
582 | if (ret) | ||
583 | goto out; | ||
584 | dev->mode_config.acquire_ctx = &ctx; | ||
579 | if (crtc_req->mode_valid) { | 585 | if (crtc_req->mode_valid) { |
580 | /* If we have a mode we need a framebuffer. */ | 586 | /* If we have a mode we need a framebuffer. */ |
581 | /* If we pass -1, set the mode with the currently bound fb */ | 587 | /* If we pass -1, set the mode with the currently bound fb */ |
@@ -696,7 +702,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, | |||
696 | set.connectors = connector_set; | 702 | set.connectors = connector_set; |
697 | set.num_connectors = crtc_req->count_connectors; | 703 | set.num_connectors = crtc_req->count_connectors; |
698 | set.fb = fb; | 704 | set.fb = fb; |
699 | ret = __drm_mode_set_config_internal(&set); | 705 | ret = __drm_mode_set_config_internal(&set, &ctx); |
700 | 706 | ||
701 | out: | 707 | out: |
702 | if (fb) | 708 | if (fb) |
@@ -710,7 +716,13 @@ out: | |||
710 | } | 716 | } |
711 | kfree(connector_set); | 717 | kfree(connector_set); |
712 | drm_mode_destroy(dev, mode); | 718 | drm_mode_destroy(dev, mode); |
713 | drm_modeset_unlock_all(dev); | 719 | if (ret == -EDEADLK) { |
720 | drm_modeset_backoff(&ctx); | ||
721 | goto retry; | ||
722 | } | ||
723 | drm_modeset_drop_locks(&ctx); | ||
724 | drm_modeset_acquire_fini(&ctx); | ||
725 | |||
714 | return ret; | 726 | return ret; |
715 | } | 727 | } |
716 | 728 | ||