On laptops which require the handler to switch DDC lines, already registered clients must reprobe their connectors if the handler registers late. This is the case on pre-retina MacBook Pros, which use a gmux controller as handler. Based (loosely) on a patch by Matthew Garrett <mjg59@xxxxxxxxxxxxx> who used an additional driver callback rather than generating a hotplug event: http://lists.freedesktop.org/archives/dri-devel/2014-June/060941.html Matthew Garrett invoked the driver callback in vga_switcheroo_enable(). On pre-retina MacBook Pros, this delayed reprobing until a second gpu registers, which may never happen if its driver is not installed or blacklisted. The MacBook Pro 2011 in particular suffers from widespread gpu soldering issues due to overheating, eventually rendering it unusable with OS X. Folks are solving this by moving to Linux and disabling the discrete gpu entirely. In those cases we can't wait for a second gpu to register, we do need to reprobe as soon as the handler registers: https://ifixit.org/blog/6882/why-i-drilled-holes-in-my-macbook-pro-and-put-it-in-the-oven/#comment-26745 Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115 Tested-by: Paul Hordiienko <pvt.gord@xxxxxxxxx> [MBP 6,2 2010 intel ILK + nvidia GT216 pre-retina] Tested-by: William Brown <william@xxxxxxxxxxxxxxxx> [MBP 8,2 2011 intel SNB + amd turks pre-retina] Tested-by: Lukas Wunner <lukas@xxxxxxxxx> [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina] Tested-by: Bruno Bierbaumer <bruno@xxxxxxxxxxxxxx> [MBP 11,3 2013 intel HSW + nvidia GK107 retina -- work in progress] Signed-off-by: Lukas Wunner <lukas@xxxxxxxxx> --- drivers/gpu/vga/vga_switcheroo.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 8027c9f..94b0b6f 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -18,6 +18,8 @@ - can_switch - check if the device is in a position to switch now */ +#include <drm/drm_crtc_helper.h> + #include <linux/module.h> #include <linux/seq_file.h> #include <linux/uaccess.h> @@ -35,6 +37,7 @@ struct vga_switcheroo_client { struct pci_dev *pdev; struct fb_info *fb_info; + struct work_struct reprobe_work; int pwr_state; const struct vga_switcheroo_client_ops *ops; int id; @@ -106,6 +109,30 @@ static void vga_switcheroo_enable(void) vgasr_priv.active = true; } +static void vga_switcheroo_reprobe_client(struct work_struct *work) +{ + struct vga_switcheroo_client *client = + container_of(work, struct vga_switcheroo_client, reprobe_work); + void (*generate_hotplug_event)(struct drm_device *); + + generate_hotplug_event = symbol_get(drm_kms_helper_hotplug_event); + if (!generate_hotplug_event) + return; + + generate_hotplug_event(pci_get_drvdata(client->pdev)); +} + +static void vga_switcheroo_reprobe_inactive_clients(void) +{ + struct vga_switcheroo_client *client; + + list_for_each_entry(client, &vgasr_priv.clients, list) + if (!client->active && client_is_vga(client)) { + cancel_work_sync(&client->reprobe_work); + schedule_work(&client->reprobe_work); + } +} + int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) { mutex_lock(&vgasr_mutex); @@ -115,11 +142,17 @@ int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) } vgasr_priv.handler = handler; + if (vga_switcheroo_ready()) { printk(KERN_INFO "vga_switcheroo: enabled\n"); vga_switcheroo_enable(); } mutex_unlock(&vgasr_mutex); + + /* clients which registered before the handler must reprobe */ + if (vgasr_priv.handler->switch_ddc) + vga_switcheroo_reprobe_inactive_clients(); + return 0; } EXPORT_SYMBOL(vga_switcheroo_register_handler); @@ -153,6 +186,7 @@ static int register_client(struct pci_dev *pdev, client->id = id; client->active = active; client->driver_power_control = driver_power_control; + INIT_WORK(&client->reprobe_work, vga_switcheroo_reprobe_client); mutex_lock(&vgasr_mutex); list_add_tail(&client->list, &vgasr_priv.clients); -- 1.8.5.2 (Apple Git-48) _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel