Date: Sun, 3 Nov 2019 21:06:06 +0000 (UTC) From: Vladimir Kondratyev <wulf@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r354313 - head/sys/dev/ichiic Message-ID: <201911032106.xA3L666M072018@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: wulf Date: Sun Nov 3 21:06:06 2019 New Revision: 354313 URL: https://svnweb.freebsd.org/changeset/base/354313 Log: [ig4] Convert polling loop from status-based to interrupt-based INTR_STAT register exposes more useful informaton then STA register does e.g. it exposes error and I2C bus STOP conditions. Make it a main source of I2C transfer state. Modified: head/sys/dev/ichiic/ig4_iic.c Modified: head/sys/dev/ichiic/ig4_iic.c ============================================================================== --- head/sys/dev/ichiic/ig4_iic.c Sun Nov 3 21:04:51 2019 (r354312) +++ head/sys/dev/ichiic/ig4_iic.c Sun Nov 3 21:06:06 2019 (r354313) @@ -198,10 +198,10 @@ set_controller(ig4iic_softc_t *sc, uint32_t ctl) } /* - * Wait up to 25ms for the requested status using a 25uS polling loop. + * Wait up to 25ms for the requested interrupt using a 25uS polling loop. */ static int -wait_status(ig4iic_softc_t *sc, uint32_t status) +wait_intr(ig4iic_softc_t *sc, uint32_t intr) { uint32_t v; int error; @@ -215,8 +215,8 @@ wait_status(ig4iic_softc_t *sc, uint32_t status) /* * Check requested status */ - v = reg_read(sc, IG4_REG_I2C_STA); - if (v & status) { + v = reg_read(sc, IG4_REG_RAW_INTR_STAT); + if (v & intr) { error = 0; break; } @@ -226,7 +226,7 @@ wait_status(ig4iic_softc_t *sc, uint32_t status) * reset the timeout if we see a change in the transmit * FIFO level as progress is being made. */ - if (status & IG4_STATUS_TX_EMPTY) { + if (intr & IG4_INTR_TX_EMPTY) { v = reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK; if (txlvl != v) { txlvl = v; @@ -241,25 +241,16 @@ wait_status(ig4iic_softc_t *sc, uint32_t status) break; /* - * When waiting for receive data let the interrupt do its - * work, otherwise poll with the lock held. + * When polling is not requested let the interrupt do its work. */ - if ((status & IG4_STATUS_RX_NOTEMPTY) && !DO_POLL(sc)) { + if (!DO_POLL(sc)) { mtx_lock(&sc->io_lock); - set_intr_mask(sc, IG4_INTR_STOP_DET | IG4_INTR_RX_FULL); + set_intr_mask(sc, intr); mtx_sleep(sc, &sc->io_lock, 0, "i2cwait", (hz + 99) / 100); /* sleep up to 10ms */ set_intr_mask(sc, 0); mtx_unlock(&sc->io_lock); count_us += 10000; - } else if ((status & IG4_STATUS_TX_EMPTY) && !DO_POLL(sc)) { - mtx_lock(&sc->io_lock); - set_intr_mask(sc, IG4_INTR_TX_EMPTY); - mtx_sleep(sc, &sc->io_lock, 0, "i2cwait", - (hz + 99) / 100); /* sleep up to 10ms */ - set_intr_mask(sc, 0); - mtx_unlock(&sc->io_lock); - count_us += 10000; } else { DELAY(25); count_us += 25; @@ -293,7 +284,7 @@ set_slave_addr(ig4iic_softc_t *sc, uint8_t slave) /* * Wait for TXFIFO to drain before disabling the controller. */ - wait_status(sc, IG4_STATUS_TX_EMPTY); + wait_intr(sc, IG4_INTR_TX_EMPTY); set_controller(sc, 0); ctl = reg_read(sc, IG4_REG_CTL); @@ -346,7 +337,7 @@ ig4iic_read(ig4iic_softc_t *sc, uint8_t *buf, uint16_t burst = sc->cfg.txfifo_depth - (reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK); if (burst <= 0) { - error = wait_status(sc, IG4_STATUS_TX_EMPTY); + error = wait_intr(sc, IG4_INTR_TX_EMPTY); if (error) break; burst = sc->cfg.txfifo_depth; @@ -376,7 +367,7 @@ ig4iic_read(ig4iic_softc_t *sc, uint8_t *buf, uint16_t buf[received++] = 0xFF & reg_read(sc, IG4_REG_DATA_CMD); } else { - error = wait_status(sc, IG4_STATUS_RX_NOTEMPTY); + error = wait_intr(sc, IG4_INTR_RX_FULL); if (error) goto out; } @@ -413,7 +404,7 @@ ig4iic_write(ig4iic_softc_t *sc, uint8_t *buf, uint16_ sent++; } if (sent < len) { - error = wait_status(sc, IG4_STATUS_TX_EMPTY); + error = wait_intr(sc, IG4_INTR_TX_EMPTY); if (error) break; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911032106.xA3L666M072018>