diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-04-11 10:26:55 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-04-12 00:21:12 -0400 |
commit | 89ced125472b8551c65526934b7f6c733a6864fa (patch) | |
tree | 33fb230e4392878537e19a01d724b9a7a00eb313 | |
parent | 1baee58638fc58248625255f5c5fcdb987f11b1f (diff) |
drm/fb-helper: Fix locking in drm_fb_helper_hotplug_event
Driver's and ->fill_modes functions are allowed to grab crtc mutexes
(for e.g. load detect). Hence we need to first only grab the general
kms mutex, and only in a second step grab all locks to do the
modesets.
This prevents a deadlock on my gm45 in the tv load detect code called
by drm_helper_probe_single_connector_modes.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 59d6b9bf204b..892ff9f95975 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -1544,10 +1544,10 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) | |||
1544 | if (!fb_helper->fb) | 1544 | if (!fb_helper->fb) |
1545 | return 0; | 1545 | return 0; |
1546 | 1546 | ||
1547 | drm_modeset_lock_all(dev); | 1547 | mutex_lock(&fb_helper->dev->mode_config.mutex); |
1548 | if (!drm_fb_helper_is_bound(fb_helper)) { | 1548 | if (!drm_fb_helper_is_bound(fb_helper)) { |
1549 | fb_helper->delayed_hotplug = true; | 1549 | fb_helper->delayed_hotplug = true; |
1550 | drm_modeset_unlock_all(dev); | 1550 | mutex_unlock(&fb_helper->dev->mode_config.mutex); |
1551 | return 0; | 1551 | return 0; |
1552 | } | 1552 | } |
1553 | DRM_DEBUG_KMS("\n"); | 1553 | DRM_DEBUG_KMS("\n"); |
@@ -1558,9 +1558,11 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) | |||
1558 | 1558 | ||
1559 | count = drm_fb_helper_probe_connector_modes(fb_helper, max_width, | 1559 | count = drm_fb_helper_probe_connector_modes(fb_helper, max_width, |
1560 | max_height); | 1560 | max_height); |
1561 | mutex_unlock(&fb_helper->dev->mode_config.mutex); | ||
1562 | |||
1563 | drm_modeset_lock_all(dev); | ||
1561 | drm_setup_crtcs(fb_helper); | 1564 | drm_setup_crtcs(fb_helper); |
1562 | drm_modeset_unlock_all(dev); | 1565 | drm_modeset_unlock_all(dev); |
1563 | |||
1564 | drm_fb_helper_set_par(fb_helper->fbdev); | 1566 | drm_fb_helper_set_par(fb_helper->fbdev); |
1565 | 1567 | ||
1566 | return 0; | 1568 | return 0; |