-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This patch is based on my analysis of the binary Apple gmux OSX driver.
Apple apparently follows for byte writes both protocols: the indexed
and the direct mapped one.
During my tests, gmux register writes and reads never failed, while
without this patch both writes and reads if done consecutively often fail.
Failed writes obviously affect switching from one GPU to another
(e.g., also during suspend/resume causing all kinds of problems: black
screen to complete system lockup).
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAlA3NZ0ACgkQ6iVUjPs37JlpJQCdF1Rla8AE2honZ1efQbWxfLOH
4ZEAnRTY85DDplkCN2yj35jXlWQq6NMO
=Eg8m
-----END PGP SIGNATURE-----
Signed-off-by: Bernhard Froemel <[email protected]>

--- a/drivers/platform/x86/apple-gmux.c 2012-08-22 22:29:06.000000000 +0200
+++ b/drivers/platform/x86/apple-gmux.c 2012-08-24 09:18:50.229362622 +0200
@@ -19,7 +19,6 @@
 #include <linux/pnp.h>
 #include <linux/apple_bl.h>
 #include <linux/slab.h>
-#include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/vga_switcheroo.h>
 #include <acpi/video.h>
@@ -113,7 +112,6 @@
        while (i && (gwr & 0x01)) {
                inb(gmux_data->iostart + GMUX_PORT_READ);
                gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE);
-               udelay(100);
                i--;
        }
 
@@ -127,11 +125,10 @@
 
        while (i && !(gwr & 0x01)) {
                gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE);
-               udelay(100);
                i--;
        }
 
-       if (gwr & 0x01)
+       if (!(gwr & 0x01))
                inb(gmux_data->iostart + GMUX_PORT_READ);
 
        return !!i;
@@ -142,8 +139,9 @@
        u8 val;
 
        mutex_lock(&gmux_data->index_lock);
-       outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ);
        gmux_index_wait_ready(gmux_data);
+       outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ);
+       gmux_index_wait_complete(gmux_data);
        val = inb(gmux_data->iostart + GMUX_PORT_VALUE);
        mutex_unlock(&gmux_data->index_lock);
 
@@ -153,6 +151,7 @@
 static void gmux_index_write8(struct apple_gmux_data *gmux_data, int port,
                              u8 val)
 {
+       outb(val, gmux_data->iostart + port);
        mutex_lock(&gmux_data->index_lock);
        outb(val, gmux_data->iostart + GMUX_PORT_VALUE);
        gmux_index_wait_ready(gmux_data);
@@ -166,8 +165,9 @@
        u32 val;
 
        mutex_lock(&gmux_data->index_lock);
-       outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ);
        gmux_index_wait_ready(gmux_data);
+       outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ);
+       gmux_index_wait_complete(gmux_data);
        val = inl(gmux_data->iostart + GMUX_PORT_VALUE);
        mutex_unlock(&gmux_data->index_lock);
 

Attachment: 01_indexed_interface_fixes.txt.sig
Description: Binary data

Reply via email to