Skip to content

Commit

Permalink
drm/fb-helper: delay hotplug handling when partially bound
Browse files Browse the repository at this point in the history
Ok, this requires quite a dance to actually hit:
1) We plug in a 2nd screen, enable it in both X and (by vt-switching)
in the fbcon.
2) We disable that screen again in with xrandr.
3) We vt-switch again, so that fbcon displays on the 2nd screen, but X
on the first screen. This obviously needs a driver that doesn't switch
off unused functions when regaining the VT.
3) When X controls the vt, we unplug that screen.

Now drm_fb_helper_hotplug_event we noticed that that some crtcs are
bound, but because we still have the fbcon on the 2nd screeen we also
have bound set. Which means the fbcon wrongly assumes it's in control
of everything an happily disables the output on the 2nd screen, but
enables its fb on the first screen.

Work around this issue by counting how many crtcs are bound and how
many are bound to fbcon and assuming that when fbcon isn't bound to
all of them, it better not touch the output configuration.

Conceptually this is the same as only restoring the fbcon output
configuration on the driver's ->lastclose, when we're sure that no one
else is using kms. So this should be consistent with existing kms
drivers.

Chris has created a separate patch for the intel ddx, but I think we
should fix this issue here regardless - the fbcon messing with the
output config while it's not fully in control simply isn't a too
polite behaviour.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=50772
Tested-by: Maxim A. Nikulin <M.A.Nikulin@gmail.com>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Daniel Vetter authored and Dave Airlie committed Jul 20, 2012
1 parent b68bdc1 commit 343065a
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions drivers/gpu/drm/drm_fb_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1353,7 +1353,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
struct drm_device *dev = fb_helper->dev;
int count = 0;
u32 max_width, max_height, bpp_sel;
bool bound = false, crtcs_bound = false;
int bound = 0, crtcs_bound = 0;
struct drm_crtc *crtc;

if (!fb_helper->fb)
Expand All @@ -1362,12 +1362,12 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
if (crtc->fb)
crtcs_bound = true;
crtcs_bound++;
if (crtc->fb == fb_helper->fb)
bound = true;
bound++;
}

if (!bound && crtcs_bound) {
if (bound < crtcs_bound) {
fb_helper->delayed_hotplug = true;
mutex_unlock(&dev->mode_config.mutex);
return 0;
Expand Down

0 comments on commit 343065a

Please sign in to comment.