apple-gmux: Assign apple_gmux_data before registering
authorMatthew Garrett <matthew.garrett@nebula.com>
Mon, 16 Nov 2015 20:38:40 +0000 (21:38 +0100)
committerDarren Hart <dvhart@linux.intel.com>
Tue, 19 Jan 2016 23:49:34 +0000 (15:49 -0800)
Registering the handler after both GPUs will trigger a DDC switch for
connector reprobing. This will oops if apple_gmux_data hasn't already
been assigned. Reorder the code to do that.

[Lukas: More generally, this commit fixes a race condition that
is triggered by invoking a handler callback between the call to
vga_switcheroo_register_handler() and the assignment of
apple_gmux_data.]

Tested-by: Pierre Moreau <pierre.morrow@free.fr>
    [MBP  5,3 2009  nvidia MCP79 + G96        pre-retina  15"]
Tested-by: Paul Hordiienko <pvt.gord@gmail.com>
    [MBP  6,2 2010  intel ILK + nvidia GT216  pre-retina  15"]
Tested-by: Lukas Wunner <lukas@wunner.de>
    [MBP  9,1 2012  intel IVB + nvidia GK107  pre-retina  15"]
Tested-by: William Brown <william@blackhats.net.au>
    [MBP  8,2 2011  intel SNB + amd turks     pre-retina  15"]
Tested-by: Bruno Bierbaumer <bruno@bierbaumer.net>
    [MBP 11,3 2013  intel HSW + nvidia GK107  retina      15"]

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Reviewed-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
drivers/platform/x86/apple-gmux.c

index 976efeb3f2ba3f377f777c91150f7afcb7b400a2..aa58d41ec46050de1f3ffd62d376fc28b06db069 100644 (file)
@@ -588,18 +588,20 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
                gmux_data->gpe = -1;
        }
 
+       apple_gmux_data = gmux_data;
+       init_completion(&gmux_data->powerchange_done);
+       gmux_enable_interrupts(gmux_data);
+
        if (vga_switcheroo_register_handler(&gmux_handler)) {
                ret = -ENODEV;
                goto err_register_handler;
        }
 
-       init_completion(&gmux_data->powerchange_done);
-       apple_gmux_data = gmux_data;
-       gmux_enable_interrupts(gmux_data);
-
        return 0;
 
 err_register_handler:
+       gmux_disable_interrupts(gmux_data);
+       apple_gmux_data = NULL;
        if (gmux_data->gpe >= 0)
                acpi_disable_gpe(NULL, gmux_data->gpe);
 err_enable_gpe: