patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / drivers / input / serio / i8042.c
index efe3c28..e9d8dab 100644 (file)
@@ -150,7 +150,7 @@ static int i8042_flush(void)
  */
 
 static int i8042_command(unsigned char *param, int command)
-{ 
+{
        unsigned long flags;
        int retval = 0, i = 0;
 
@@ -161,7 +161,7 @@ static int i8042_command(unsigned char *param, int command)
                dbg("%02x -> i8042 (command)", command & 0xff);
                i8042_write_command(command & 0xff);
        }
-       
+
        if (!retval)
                for (i = 0; i < ((command >> 12) & 0xf); i++) {
                        if ((retval = i8042_wait_write())) break;
@@ -172,7 +172,7 @@ static int i8042_command(unsigned char *param, int command)
        if (!retval)
                for (i = 0; i < ((command >> 8) & 0xf); i++) {
                        if ((retval = i8042_wait_read())) break;
-                       if (i8042_read_status() & I8042_STR_AUXDATA) 
+                       if (i8042_read_status() & I8042_STR_AUXDATA)
                                param[i] = ~i8042_read_data();
                        else
                                param[i] = i8042_read_data();
@@ -415,17 +415,17 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                } else dfl = 0;
 
                dbg("%02x <- i8042 (interrupt, aux%d, %d%s%s)",
-                       data, (str >> 6), irq, 
+                       data, (str >> 6), irq,
                        dfl & SERIO_PARITY ? ", bad parity" : "",
                        dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
                serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl, regs);
-               
+
                goto irq_ret;
        }
 
        dbg("%02x <- i8042 (interrupt, %s, %d%s%s)",
-               data, (str & I8042_STR_AUXDATA) ? "aux" : "kbd", irq, 
+               data, (str & I8042_STR_AUXDATA) ? "aux" : "kbd", irq,
                dfl & SERIO_PARITY ? ", bad parity" : "",
                dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
@@ -474,8 +474,17 @@ static int i8042_enable_mux_mode(struct i8042_values *values, unsigned char *mux
        if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0xa9)
                return -1;
        param = 0xa4;
-       if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b)
+       if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b) {
+
+/*
+ * Do another loop test with the 0x5a value. Doing anything else upsets
+ * Profusion/ServerWorks OSB4 chipsets.
+ */
+
+               param = 0x5a;
+               i8042_command(&param, I8042_CMD_AUX_LOOP);
                return -1;
+       }
 
        if (mux_version)
                *mux_version = ~param;
@@ -530,10 +539,10 @@ static int __init i8042_check_mux(struct i8042_values *values)
 
        if (i8042_enable_mux_mode(values, &mux_version))
                return -1;
-       
+
        /* Workaround for broken chips which seem to support MUX, but in reality don't. */
-       /* They all report version 12.10 */
-       if (mux_version == 0xCA)
+       /* They all report version 10.12 */
+       if (mux_version == 0xAC)
                return -1;
 
        printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
@@ -598,7 +607,7 @@ static int __init i8042_check_aux(struct i8042_values *values)
 /*
  * Bit assignment test - filters out PS/2 i8042's in AT mode
  */
-       
+
        if (i8042_command(&param, I8042_CMD_AUX_DISABLE))
                return -1;
        if (i8042_command(&param, I8042_CMD_CTL_RCTR) || (~param & I8042_CTR_AUXDIS)) {
@@ -609,7 +618,7 @@ static int __init i8042_check_aux(struct i8042_values *values)
        if (i8042_command(&param, I8042_CMD_AUX_ENABLE))
                return -1;
        if (i8042_command(&param, I8042_CMD_CTL_RCTR) || (param & I8042_CTR_AUXDIS))
-               return -1;      
+               return -1;
 
 /*
  * Disable the interface.
@@ -639,7 +648,7 @@ static int __init i8042_port_register(struct i8042_values *values, struct serio
        if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
                printk(KERN_WARNING "i8042.c: Can't write CTR while registering.\n");
                values->exists = 0;
-               return -1; 
+               return -1;
        }
 
        printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n",
@@ -868,7 +877,7 @@ static int i8042_controller_resume(void)
 static int i8042_notify_sys(struct notifier_block *this, unsigned long code,
                            void *unused)
 {
-        if (code==SYS_DOWN || code==SYS_HALT) 
+        if (code == SYS_DOWN || code == SYS_HALT)
                i8042_controller_cleanup();
         return NOTIFY_DONE;
 }
@@ -997,19 +1006,18 @@ void __exit i8042_exit(void)
                sysdev_class_unregister(&kbc_sysclass);
        }
 
-       del_timer_sync(&i8042_timer);
-
        i8042_controller_cleanup();
-       
+
        if (i8042_kbd_values.exists)
                serio_unregister_port(&i8042_kbd_port);
 
        if (i8042_aux_values.exists)
                serio_unregister_port(&i8042_aux_port);
-       
+
        for (i = 0; i < 4; i++)
                if (i8042_mux_values[i].exists)
                        serio_unregister_port(i8042_mux_port + i);
+       del_timer_sync(&i8042_timer);
 
        i8042_platform_exit();
 }