diff options
author | Vladimir Kondratyev <wulf@FreeBSD.org> | 2019-11-03 20:42:04 +0000 |
---|---|---|
committer | Vladimir Kondratyev <wulf@FreeBSD.org> | 2019-11-03 20:42:04 +0000 |
commit | 21e459c61b2673db69a541b10668d2e9b752685b (patch) | |
tree | 18401755a9dd97b7bd135d324dbdd4e8445a2248 | |
parent | bf9c3c58cac8447eb57f9b39fe4d55c06e42ed8a (diff) |
Notes
-rw-r--r-- | sys/dev/ichiic/ig4_acpi.c | 5 | ||||
-rw-r--r-- | sys/dev/ichiic/ig4_iic.c | 36 | ||||
-rw-r--r-- | sys/dev/ichiic/ig4_var.h | 2 |
3 files changed, 20 insertions, 23 deletions
diff --git a/sys/dev/ichiic/ig4_acpi.c b/sys/dev/ichiic/ig4_acpi.c index fad0377c72e8..e56b378f1767 100644 --- a/sys/dev/ichiic/ig4_acpi.c +++ b/sys/dev/ichiic/ig4_acpi.c @@ -69,18 +69,15 @@ static int ig4iic_acpi_probe(device_t dev) { ig4iic_softc_t *sc; - char *hid; int rv; sc = device_get_softc(dev); if (acpi_disabled("ig4iic")) return (ENXIO); - rv = ACPI_ID_PROBE(device_get_parent(dev), dev, ig4iic_ids, &hid); + rv = ACPI_ID_PROBE(device_get_parent(dev), dev, ig4iic_ids, NULL); if (rv > 0) return (rv); - if (strcmp("AMDI0010", hid) == 0) - sc->access_intr_mask = 1; device_set_desc(dev, "Designware I2C Controller"); return (rv); } diff --git a/sys/dev/ichiic/ig4_iic.c b/sys/dev/ichiic/ig4_iic.c index 1d26dff59a7d..fcf513389be3 100644 --- a/sys/dev/ichiic/ig4_iic.c +++ b/sys/dev/ichiic/ig4_iic.c @@ -98,6 +98,15 @@ reg_read(ig4iic_softc_t *sc, uint32_t reg) return (value); } +static void +set_intr_mask(ig4iic_softc_t *sc, uint32_t val) +{ + if (sc->intr_mask != val) { + reg_write(sc, IG4_REG_INTR_MASK, val); + sc->intr_mask = val; + } +} + /* * Enable or disable the controller and wait for the controller to acknowledge * the state change. @@ -113,12 +122,9 @@ set_controller(ig4iic_softc_t *sc, uint32_t ctl) * 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); + set_intr_mask(sc, 0); + if (ctl & IG4_I2C_ENABLE) 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 = IIC_ETIMEOUT; @@ -196,8 +202,10 @@ wait_status(ig4iic_softc_t *sc, uint32_t status) * work, otherwise poll with the lock held. */ if (status & IG4_STATUS_RX_NOTEMPTY) { + set_intr_mask(sc, IG4_INTR_STOP_DET | IG4_INTR_RX_FULL); mtx_sleep(sc, &sc->io_lock, 0, "i2cwait", (hz + 99) / 100); /* sleep up to 10ms */ + set_intr_mask(sc, 0); count_us += 10000; } else { DELAY(25); @@ -579,6 +587,10 @@ ig4iic_attach(ig4iic_softc_t *sc) v = reg_read(sc, IG4_REG_SS_SCL_LCNT); reg_write(sc, IG4_REG_FS_SCL_LCNT, v); + reg_read(sc, IG4_REG_CLR_INTR); + reg_write(sc, IG4_REG_INTR_MASK, 0); + sc->intr_mask = 0; + /* * Program based on a 25000 Hz clock. This is a bit of a * hack (obviously). The defaults are 400 and 470 for standard @@ -725,7 +737,7 @@ ig4iic_intr(void *cookie) uint32_t status; mtx_lock(&sc->io_lock); -/* reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET);*/ + set_intr_mask(sc, 0); reg_read(sc, IG4_REG_CLR_INTR); status = reg_read(sc, IG4_REG_I2C_STA); while (status & IG4_STATUS_RX_NOTEMPTY) { @@ -735,18 +747,6 @@ ig4iic_intr(void *cookie) status = reg_read(sc, IG4_REG_I2C_STA); } - /* - * Workaround to trigger pending interrupt if IG4_REG_INTR_STAT - * is changed after clearing it - */ - if (sc->access_intr_mask != 0) { - status = reg_read(sc, IG4_REG_INTR_MASK); - if (status != 0) { - reg_write(sc, IG4_REG_INTR_MASK, 0); - reg_write(sc, IG4_REG_INTR_MASK, status); - } - } - wakeup(sc); mtx_unlock(&sc->io_lock); } diff --git a/sys/dev/ichiic/ig4_var.h b/sys/dev/ichiic/ig4_var.h index b679cb6db6d9..962a797a4ac1 100644 --- a/sys/dev/ichiic/ig4_var.h +++ b/sys/dev/ichiic/ig4_var.h @@ -65,6 +65,7 @@ struct ig4iic_softc { int rnext; int rpos; char rbuf[IG4_RBUFSIZE]; + uint32_t intr_mask; int error; uint8_t last_slave; int platform_attached : 1; @@ -72,7 +73,6 @@ struct ig4iic_softc { int slave_valid : 1; int read_started : 1; int write_started : 1; - int access_intr_mask : 1; /* * Locking semantics: |