Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh...
[pandora-kernel.git] / drivers / input / serio / i8042.c
index 7e3141f..ec195a3 100644 (file)
@@ -76,13 +76,6 @@ module_param_named(debug, i8042_debug, bool, 0600);
 MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off");
 #endif
 
-__obsolete_setup("i8042_noaux");
-__obsolete_setup("i8042_nomux");
-__obsolete_setup("i8042_unlock");
-__obsolete_setup("i8042_reset");
-__obsolete_setup("i8042_direct");
-__obsolete_setup("i8042_dumbkbd");
-
 #include "i8042.h"
 
 static DEFINE_SPINLOCK(i8042_lock);
@@ -255,25 +248,10 @@ static int i8042_kbd_write(struct serio *port, unsigned char c)
 static int i8042_aux_write(struct serio *serio, unsigned char c)
 {
        struct i8042_port *port = serio->port_data;
-       int retval;
-
-/*
- * Send the byte out.
- */
-
-       if (port->mux == -1)
-               retval = i8042_command(&c, I8042_CMD_AUX_SEND);
-       else
-               retval = i8042_command(&c, I8042_CMD_MUX_SEND + port->mux);
 
-/*
- * Make sure the interrupt happens and the character is received even
- * in the case the IRQ isn't wired, so that we can receive further
- * characters later.
- */
-
-       i8042_interrupt(0, NULL);
-       return retval;
+       return i8042_command(&c, port->mux == -1 ?
+                                       I8042_CMD_AUX_SEND :
+                                       I8042_CMD_MUX_SEND + port->mux);
 }
 
 /*
@@ -337,23 +315,27 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
                dfl = 0;
                if (str & I8042_STR_MUXERR) {
                        dbg("MUX error, status is %02x, data is %02x", str, data);
-                       switch (data) {
-                               default:
 /*
  * When MUXERR condition is signalled the data register can only contain
  * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately
- * it is not always the case. Some KBC just get confused which port the
- * data came from and signal error leaving the data intact. They _do not_
- * revert to legacy mode (actually I've never seen KBC reverting to legacy
- * mode yet, when we see one we'll add proper handling).
- * Anyway, we will assume that the data came from the same serio last byte
+ * it is not always the case. Some KBCs also report 0xfc when there is
+ * nothing connected to the port while others sometimes get confused which
+ * port the data came from and signal error leaving the data intact. They
+ * _do not_ revert to legacy mode (actually I've never seen KBC reverting
+ * to legacy mode yet, when we see one we'll add proper handling).
+ * Anyway, we process 0xfc, 0xfd, 0xfe and 0xff as timeouts, and for the
+ * rest assume that the data came from the same serio last byte
  * was transmitted (if transmission happened not too long ago).
  */
+
+                       switch (data) {
+                               default:
                                        if (time_before(jiffies, last_transmit + HZ/10)) {
                                                str = last_str;
                                                break;
                                        }
                                        /* fall through - report timeout */
+                               case 0xfc:
                                case 0xfd:
                                case 0xfe: dfl = SERIO_TIMEOUT; data = 0xfe; break;
                                case 0xff: dfl = SERIO_PARITY;  data = 0xfe; break;
@@ -382,7 +364,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
        if (unlikely(i8042_suppress_kbd_ack))
                if (port_no == I8042_KBD_PORT_NO &&
                    (data == 0xfa || data == 0xfe)) {
-                       i8042_suppress_kbd_ack = 0;
+                       i8042_suppress_kbd_ack--;
                        goto out;
                }
 
@@ -554,6 +536,7 @@ static int __devinit i8042_check_aux(void)
 {
        int retval = -1;
        int irq_registered = 0;
+       int aux_loop_broken = 0;
        unsigned long flags;
        unsigned char param;
 
@@ -583,6 +566,8 @@ static int __devinit i8042_check_aux(void)
                if (i8042_command(&param, I8042_CMD_AUX_TEST) ||
                    (param && param != 0xfa && param != 0xff))
                        return -1;
+
+               aux_loop_broken = 1;
        }
 
 /*
@@ -606,7 +591,7 @@ static int __devinit i8042_check_aux(void)
  * used it for a PCI card or somethig else.
  */
 
-       if (i8042_noloop) {
+       if (i8042_noloop || aux_loop_broken) {
 /*
  * Without LOOP command we can't test AUX IRQ delivery. Assume the port
  * is working and hope we are right.
@@ -732,7 +717,7 @@ static int i8042_controller_init(void)
        if (~i8042_read_status() & I8042_STR_KEYLOCK) {
                if (i8042_unlock)
                        i8042_ctr |= I8042_CTR_IGNKEYLOCK;
-                else
+               else
                        printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n");
        }
        spin_unlock_irqrestore(&i8042_lock, flags);
@@ -798,27 +783,6 @@ static void i8042_controller_reset(void)
 }
 
 
-/*
- * Here we try to reset everything back to a state in which the BIOS will be
- * able to talk to the hardware when rebooting.
- */
-
-static void i8042_controller_cleanup(void)
-{
-       int i;
-
-/*
- * Reset anything that is connected to the ports.
- */
-
-       for (i = 0; i < I8042_NUM_PORTS; i++)
-               if (i8042_ports[i].serio)
-                       serio_cleanup(i8042_ports[i].serio);
-
-       i8042_controller_reset();
-}
-
-
 /*
  * i8042_panic_blink() will flash the keyboard LEDs and is called when
  * kernel panics. Flashing LEDs is useful for users running X who may
@@ -849,13 +813,14 @@ static long i8042_panic_blink(long count)
        led ^= 0x01 | 0x04;
        while (i8042_read_status() & I8042_STR_IBF)
                DELAY;
-       i8042_suppress_kbd_ack = 1;
+       dbg("%02x -> i8042 (panic blink)", 0xed);
+       i8042_suppress_kbd_ack = 2;
        i8042_write_data(0xed); /* set leds */
        DELAY;
        while (i8042_read_status() & I8042_STR_IBF)
                DELAY;
        DELAY;
-       i8042_suppress_kbd_ack = 1;
+       dbg("%02x -> i8042 (panic blink)", led);
        i8042_write_data(led);
        DELAY;
        last_blink = count;
@@ -864,13 +829,22 @@ static long i8042_panic_blink(long count)
 
 #undef DELAY
 
+#ifdef CONFIG_PM
 /*
- * Here we try to restore the original BIOS settings
+ * Here we try to restore the original BIOS settings. We only want to
+ * do that once, when we really suspend, not when we taking memory
+ * snapshot for swsusp (in this case we'll perform required cleanup
+ * as part of shutdown process).
  */
 
 static int i8042_suspend(struct platform_device *dev, pm_message_t state)
 {
-       i8042_controller_cleanup();
+       if (dev->dev.power.power_state.event != state.event) {
+               if (state.event == PM_EVENT_SUSPEND)
+                       i8042_controller_reset();
+
+               dev->dev.power.power_state = state;
+       }
 
        return 0;
 }
@@ -884,6 +858,12 @@ static int i8042_resume(struct platform_device *dev)
 {
        int error;
 
+/*
+ * Do not bother with restoring state if we haven't suspened yet
+ */
+       if (dev->dev.power.power_state.event == PM_EVENT_ON)
+               return 0;
+
        error = i8042_controller_check();
        if (error)
                return error;
@@ -893,9 +873,12 @@ static int i8042_resume(struct platform_device *dev)
                return error;
 
 /*
- * Restore pre-resume CTR value and disable all ports
+ * Restore original CTR value and disable all ports
  */
 
+       i8042_ctr = i8042_initial_ctr;
+       if (i8042_direct)
+               i8042_ctr &= ~I8042_CTR_XLATE;
        i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS;
        i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT);
        if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
@@ -916,8 +899,11 @@ static int i8042_resume(struct platform_device *dev)
 
        i8042_interrupt(0, NULL);
 
+       dev->dev.power.power_state = PMSG_ON;
+
        return 0;
 }
+#endif /* CONFIG_PM */
 
 /*
  * We need to reset the 8042 back to original mode on system shutdown,
@@ -926,7 +912,7 @@ static int i8042_resume(struct platform_device *dev)
 
 static void i8042_shutdown(struct platform_device *dev)
 {
-       i8042_controller_cleanup();
+       i8042_controller_reset();
 }
 
 static int __devinit i8042_create_kbd_port(void)
@@ -1161,9 +1147,11 @@ static struct platform_driver i8042_driver = {
        },
        .probe          = i8042_probe,
        .remove         = __devexit_p(i8042_remove),
+       .shutdown       = i8042_shutdown,
+#ifdef CONFIG_PM
        .suspend        = i8042_suspend,
        .resume         = i8042_resume,
-       .shutdown       = i8042_shutdown,
+#endif
 };
 
 static int __init i8042_init(void)