If the handler registers late, already registered clients must
reprobe their connectors in case they require the handler to
switch DDC lines. That is the case on MacBook Pros, which use
a gmux chip as handler.

Inspired by Matthew Garrett, who did this in vga_switcheroo_enable()
instead, which delayed reprobing until a second gpu registers.
Probably makes sense to do this as early as possible, particularly
since a second gpu may never register if its driver is blacklisted
or not installed:
http://lists.freedesktop.org/archives/dri-devel/2014-June/060941.html

Signed-off-by: Lukas Wunner <lukas at wunner.de>
---
 drivers/gpu/vga/vga_switcheroo.c | 8 ++++++++
 include/linux/vga_switcheroo.h   | 1 +
 2 files changed, 9 insertions(+)

diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index 062fafe..3b13e9a 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -108,6 +108,8 @@ static void vga_switcheroo_enable(void)

 int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler)
 {
+       struct vga_switcheroo_client *client;
+
        mutex_lock(&vgasr_mutex);
        if (vgasr_priv.handler) {
                mutex_unlock(&vgasr_mutex);
@@ -115,6 +117,12 @@ int vga_switcheroo_register_handler(struct 
vga_switcheroo_handler *handler)
        }

        vgasr_priv.handler = handler;
+
+       /* clients which registered before the handler must reprobe */
+       list_for_each_entry(client, &vgasr_priv.clients, list)
+               if (!client->active && client->ops->reprobe_connectors)
+                       client->ops->reprobe_connectors(client->pdev);
+
        if (vga_switcheroo_ready()) {
                printk(KERN_INFO "vga_switcheroo: enabled\n");
                vga_switcheroo_enable();
diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h
index 60c9d65..c3ad8bf 100644
--- a/include/linux/vga_switcheroo.h
+++ b/include/linux/vga_switcheroo.h
@@ -40,6 +40,7 @@ struct vga_switcheroo_handler {
 struct vga_switcheroo_client_ops {
        void (*set_gpu_state)(struct pci_dev *dev, enum vga_switcheroo_state);
        void (*reprobe)(struct pci_dev *dev);
+       void (*reprobe_connectors)(struct pci_dev *dev);
        bool (*can_switch)(struct pci_dev *dev);
 };

-- 
1.8.5.2 (Apple Git-48)

Reply via email to