From 799fd2ee8e6ef8775eb88967dce9024837d2edfe Mon Sep 17 00:00:00 2001 From: wulf Date: Sun, 3 Nov 2019 20:51:22 +0000 Subject: [PATCH] [ig4] Add support for polled mode Currently ig4 internally depends on it's own interrupts and uses mtx_sleep() to wait for them. That means it can not be used from any context where sleeping is disallowed e.g. on cold boot, from DDB/KDB, from other device driver's interrupt handlers and so on. This change replaces sleeps with busy loops in cold boot and DDB cases. --- sys/dev/ichiic/ig4_iic.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/dev/ichiic/ig4_iic.c b/sys/dev/ichiic/ig4_iic.c index 8871b41490a5..9199e23ec346 100644 --- a/sys/dev/ichiic/ig4_iic.c +++ b/sys/dev/ichiic/ig4_iic.c @@ -48,8 +48,10 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include +#include #include #include #include @@ -70,6 +72,8 @@ __FBSDID("$FreeBSD$"); #define TRANS_PCALL 2 #define TRANS_BLOCK 3 +#define DO_POLL(sc) (cold || kdb_active || SCHEDULER_STOPPED()) + static void ig4iic_start(void *xdev); static void ig4iic_intr(void *cookie); static void ig4iic_dump(ig4iic_softc_t *sc); @@ -187,7 +191,7 @@ wait_status(ig4iic_softc_t *sc, uint32_t status) * When waiting for receive data let the interrupt do its * work, otherwise poll with the lock held. */ - if (status & IG4_STATUS_RX_NOTEMPTY) { + if ((status & IG4_STATUS_RX_NOTEMPTY) && !DO_POLL(sc)) { mtx_lock(&sc->io_lock); set_intr_mask(sc, IG4_INTR_STOP_DET | IG4_INTR_RX_FULL); mtx_sleep(sc, &sc->io_lock, 0, "i2cwait",