aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_crtc.c26
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
450static int __drm_mode_set_config_internal(struct drm_mode_set *set) 450static 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}
502EXPORT_SYMBOL(drm_mode_set_config_internal); 503EXPORT_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);
580retry:
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
701out: 707out:
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