data->irdata_count = 0;
        data->irdata_off = 0;
        data->irdata_error = 0;
+       data->idle_count = 0;
 }
 
 /* Adds one bit of irdata */
                }
 
                wbcir_reset_irdata(data);
-               data->idle_count = 0;
        }
 
 out:
 
 /*****************************************************************************
  *
- * SUSPEND/RESUME FUNCTIONS
+ * SETUP/INIT/SUSPEND/RESUME FUNCTIONS
  *
  *****************************************************************************/
 
        }
 
        /* Disable interrupts */
+       wbcir_select_bank(data, WBCIR_BANK_0);
        outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
+
+       /*
+        * ACPI will set the HW disable bit for SP3 which means that the
+        * output signals are left in an undefined state which may cause
+        * spurious interrupts which we need to ignore until the hardware
+        * is reinitialized.
+        */
+       disable_irq(data->irq);
 }
 
 static int
        return 0;
 }
 
-static int
-wbcir_resume(struct pnp_dev *device)
-{
-       struct wbcir_data *data = pnp_get_drvdata(device);
-
-       /* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */
-       wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07);
-
-       /* Clear CEIR_EN */
-       wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01);
-
-       /* Enable interrupts */
-       wbcir_reset_irdata(data);
-       outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
-
-       return 0;
-}
-
-
-
-/*****************************************************************************
- *
- * SETUP/INIT FUNCTIONS
- *
- *****************************************************************************/
-
 static void
-wbcir_cfg_ceir(struct wbcir_data *data)
+wbcir_init_hw(struct wbcir_data *data)
 {
        u8 tmp;
 
+       /* Disable interrupts */
+       wbcir_select_bank(data, WBCIR_BANK_0);
+       outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
+
        /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */
        tmp = protocol << 4;
        if (invert)
         * set SP3_IRRX_SW to binary 01, helpfully not documented
         */
        outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS);
+
+       /* Enable extended mode */
+       wbcir_select_bank(data, WBCIR_BANK_2);
+       outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1);
+
+       /*
+        * Configure baud generator, IR data will be sampled at
+        * a bitrate of: (24Mhz * prescaler) / (divisor * 16).
+        *
+        * The ECIR registers include a flag to change the
+        * 24Mhz clock freq to 48Mhz.
+        *
+        * It's not documented in the specs, but fifo levels
+        * other than 16 seems to be unsupported.
+        */
+
+       /* prescaler 1.0, tx/rx fifo lvl 16 */
+       outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2);
+
+       /* Set baud divisor to generate one byte per bit/cell */
+       switch (protocol) {
+       case IR_PROTOCOL_RC5:
+               outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL);
+               break;
+       case IR_PROTOCOL_RC6:
+               outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL);
+               break;
+       case IR_PROTOCOL_NEC:
+               outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL);
+               break;
+       }
+       outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH);
+
+       /* Set CEIR mode */
+       wbcir_select_bank(data, WBCIR_BANK_0);
+       outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR);
+       inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */
+       inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */
+
+       /* Disable RX demod, run-length encoding/decoding, set freq span */
+       wbcir_select_bank(data, WBCIR_BANK_7);
+       outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG);
+
+       /* Disable timer */
+       wbcir_select_bank(data, WBCIR_BANK_4);
+       outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1);
+
+       /* Enable MSR interrupt, Clear AUX_IRX */
+       wbcir_select_bank(data, WBCIR_BANK_5);
+       outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2);
+
+       /* Disable CRC */
+       wbcir_select_bank(data, WBCIR_BANK_6);
+       outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3);
+
+       /* Set RX/TX (de)modulation freq, not really used */
+       wbcir_select_bank(data, WBCIR_BANK_7);
+       outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC);
+       outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC);
+
+       /* Set invert and pin direction */
+       if (invert)
+               outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4);
+       else
+               outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4);
+
+       /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */
+       wbcir_select_bank(data, WBCIR_BANK_0);
+       outb(0x97, data->sbase + WBCIR_REG_SP3_FCR);
+
+       /* Clear AUX status bits */
+       outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
+
+       /* Enable interrupts */
+       wbcir_reset_irdata(data);
+       outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
+}
+
+static int
+wbcir_resume(struct pnp_dev *device)
+{
+       struct wbcir_data *data = pnp_get_drvdata(device);
+
+       wbcir_init_hw(data);
+       enable_irq(data->irq);
+
+       return 0;
 }
 
 static int __devinit
 
        device_init_wakeup(&device->dev, 1);
 
-       wbcir_cfg_ceir(data);
-
-       /* Disable interrupts */
-       wbcir_select_bank(data, WBCIR_BANK_0);
-       outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
-
-       /* Enable extended mode */
-       wbcir_select_bank(data, WBCIR_BANK_2);
-       outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1);
-
-       /*
-        * Configure baud generator, IR data will be sampled at
-        * a bitrate of: (24Mhz * prescaler) / (divisor * 16).
-        *
-        * The ECIR registers include a flag to change the
-        * 24Mhz clock freq to 48Mhz.
-        *
-        * It's not documented in the specs, but fifo levels
-        * other than 16 seems to be unsupported.
-        */
-
-       /* prescaler 1.0, tx/rx fifo lvl 16 */
-       outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2);
-
-       /* Set baud divisor to generate one byte per bit/cell */
-       switch (protocol) {
-       case IR_PROTOCOL_RC5:
-               outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL);
-               break;
-       case IR_PROTOCOL_RC6:
-               outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL);
-               break;
-       case IR_PROTOCOL_NEC:
-               outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL);
-               break;
-       }
-       outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH);
-
-       /* Set CEIR mode */
-       wbcir_select_bank(data, WBCIR_BANK_0);
-       outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR);
-       inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */
-       inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */
-
-       /* Disable RX demod, run-length encoding/decoding, set freq span */
-       wbcir_select_bank(data, WBCIR_BANK_7);
-       outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG);
-
-       /* Disable timer */
-       wbcir_select_bank(data, WBCIR_BANK_4);
-       outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1);
-
-       /* Enable MSR interrupt, Clear AUX_IRX */
-       wbcir_select_bank(data, WBCIR_BANK_5);
-       outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2);
-
-       /* Disable CRC */
-       wbcir_select_bank(data, WBCIR_BANK_6);
-       outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3);
-
-       /* Set RX/TX (de)modulation freq, not really used */
-       wbcir_select_bank(data, WBCIR_BANK_7);
-       outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC);
-       outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC);
-
-       /* Set invert and pin direction */
-       if (invert)
-               outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4);
-       else
-               outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4);
-
-       /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */
-       wbcir_select_bank(data, WBCIR_BANK_0);
-       outb(0x97, data->sbase + WBCIR_REG_SP3_FCR);
-
-       /* Clear AUX status bits */
-       outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
-
-       /* Enable interrupts */
-       outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
+       wbcir_init_hw(data);
 
        return 0;