Index: head/sys/dev/ichiic/ig4_iic.c =================================================================== --- head/sys/dev/ichiic/ig4_iic.c +++ head/sys/dev/ichiic/ig4_iic.c @@ -108,6 +108,17 @@ int error; uint32_t v; + /* + * When the controller is enabled, interrupt on STOP detect + * or receive character ready and clear pending interrupts. + */ + if (ctl & IG4_I2C_ENABLE) { + reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET | + IG4_INTR_RX_FULL); + reg_read(sc, IG4_REG_CLR_INTR); + } else + reg_write(sc, IG4_REG_INTR_MASK, 0); + reg_write(sc, IG4_REG_I2C_EN, ctl); error = SMB_ETIMEOUT; @@ -553,11 +564,6 @@ reg_write(sc, IG4_REG_RESETS, IG4_RESETS_DEASSERT); #endif - /* - * Interrupt on STOP detect or receive character ready - */ - reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET | - IG4_INTR_RX_FULL); mtx_lock(&sc->io_lock); if (set_controller(sc, 0)) device_printf(sc->dev, "controller error during attach-1\n"); @@ -574,7 +580,8 @@ sc->enum_hook.ich_func = ig4iic_start; sc->enum_hook.ich_arg = sc->dev; - /* We have to wait until interrupts are enabled. I2C read and write + /* + * We have to wait until interrupts are enabled. I2C read and write * only works if the interrupts are available. */ if (config_intrhook_establish(&sc->enum_hook) != 0) @@ -628,7 +635,6 @@ sc->smb = NULL; sc->intr_handle = NULL; reg_write(sc, IG4_REG_INTR_MASK, 0); - reg_read(sc, IG4_REG_CLR_INTR); set_controller(sc, 0); mtx_unlock(&sc->io_lock); @@ -917,6 +923,7 @@ mtx_lock(&sc->io_lock); /* reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET);*/ + reg_read(sc, IG4_REG_CLR_INTR); status = reg_read(sc, IG4_REG_I2C_STA); while (status & IG4_STATUS_RX_NOTEMPTY) { sc->rbuf[sc->rnext & IG4_RBUFMASK] = @@ -924,7 +931,6 @@ ++sc->rnext; status = reg_read(sc, IG4_REG_I2C_STA); } - reg_read(sc, IG4_REG_CLR_INTR); wakeup(sc); mtx_unlock(&sc->io_lock); }