port->serio = NULL;
 }
 
+/*
+ * i8042_filter() filters out unwanted bytes from the input data stream.
+ * It is called from i8042_interrupt and thus is running with interrupts
+ * off and i8042_lock held.
+ */
+static bool i8042_filter(unsigned char data, unsigned char str)
+{
+       if (unlikely(i8042_suppress_kbd_ack)) {
+               if ((~str & I8042_STR_AUXDATA) &&
+                   (data == 0xfa || data == 0xfe)) {
+                       i8042_suppress_kbd_ack--;
+                       dbg("Extra keyboard ACK - filtered out\n");
+                       return true;
+               }
+       }
+
+       return false;
+}
+
 /*
  * i8042_interrupt() is the most important function in this driver -
  * it handles the interrupts from the i8042, and sends incoming bytes
        unsigned char str, data;
        unsigned int dfl;
        unsigned int port_no;
+       bool filtered;
        int ret = 1;
 
        spin_lock_irqsave(&i8042_lock, flags);
+
        str = i8042_read_status();
        if (unlikely(~str & I8042_STR_OBF)) {
                spin_unlock_irqrestore(&i8042_lock, flags);
                ret = 0;
                goto out;
        }
+
        data = i8042_read_data();
-       spin_unlock_irqrestore(&i8042_lock, flags);
 
        if (i8042_mux_present && (str & I8042_STR_AUXDATA)) {
                static unsigned long last_transmit;
            dfl & SERIO_PARITY ? ", bad parity" : "",
            dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
-       if (unlikely(i8042_suppress_kbd_ack))
-               if (port_no == I8042_KBD_PORT_NO &&
-                   (data == 0xfa || data == 0xfe)) {
-                       i8042_suppress_kbd_ack--;
-                       goto out;
-               }
+       filtered = i8042_filter(data, str);
+
+       spin_unlock_irqrestore(&i8042_lock, flags);
 
-       if (likely(port->exists))
+       if (likely(port->exists && !filtered))
                serio_interrupt(port->serio, data, dfl);
 
  out: