• Lukas Wunner's avatar
    vga_switcheroo: Add support for switching only the DDC · e4cb81d7
    Lukas Wunner authored
    Originally by Seth Forshee <seth.forshee@canonical.com>, 2012-10-04:
        During graphics driver initialization it's useful to be able to mux
        only the DDC to the inactive client in order to read the EDID. Add
        a switch_ddc callback to allow capable handlers to provide this
        functionality, and add vga_switcheroo_switch_ddc() to allow DRM
        to mux only the DDC.
    
    Modified by Dave Airlie <airlied@gmail.com>, 2012-12-22:
        I can't figure out why I didn't like this, but I rewrote this [...]
        to lock/unlock the ddc lines [...]. I think I'd prefer something
        like that otherwise the interface got really ugly.
    
    Modified by Lukas Wunner <lukas@wunner.de>, 2015-04 - 2015-10:
        Change semantics of ->switch_ddc handler callback to return previous
        DDC owner. Original version tried to determine previous DDC owner
        with find_active_client() but this fails if the inactive client
        registers before the active client.
    
        Don't lock vgasr_mutex in _lock_ddc() / _unlock_ddc(), it can cause
        deadlocks because (a) during switch (with vgasr_mutex already held),
        GPU is woken and probes its outputs, tries to re-acquire vgasr_mutex
        to lock DDC lines; (b) Likewise during switch, GPU is suspended and
        calls cancel_delayed_work_sync() to stop output polling, if poll
        task is running at this moment we may wait forever for it to finish.
    
        Instead, lock mux_hw_lock when unregistering the handler because
        the only reason why we'd want to lock vgasr_mutex in _lock_ddc() /
        _unlock_ddc() is to block the handler from disappearing while DDC
        lines are switched.
    
        Also acquire mux_hw_lock in stage2 to avoid race condition where
        reading the EDID and switching happens simultaneously. Likewise on
        MIGD / MDIS commands and on runtime suspend.
    
        v2.1: Overhaul locking, squash commits (Daniel Vetter)
    
        v2.2: Readability improvements (Thierry Reding)
    
        v2.3: Overhaul locking once more
    
        v2.4: Retain semantics of ->switchto handler callback to switch all
              pins, including DDC (Daniel Vetter)
    
        v5:   Rename ddc_lock to mux_hw_lock: Since we acquire this both
              when calling ->switch_ddc and ->switchto, it protects not just
              access to the DDC lines but to the mux in general. This is in
              line with the DRM convention to use low-level locks to avoid
              concurrent hw access (e.g. i2c, dp_aux) which are often called
              hw_lock (Daniel Vetter)
    
    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115Tested-by: default avatarLukas Wunner <lukas@wunner.de>
        [MBP  9,1 2012  intel IVB + nvidia GK107  pre-retina  15"]
    Cc: Seth Forshee <seth.forshee@canonical.com>
    Cc: Dave Airlie <airlied@gmail.com>
    Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
    Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
    Link: http://patchwork.freedesktop.org/patch/msgid/e81ae9722b84c5ed591805fee3ea6dbf5dc6c4b3.1452525860.git.lukas@wunner.de
    e4cb81d7
vga_switcheroo.c 33.4 KB