Author: jmcneill Date: Sun May 15 16:43:47 2016 New Revision: 299862 URL: https://svnweb.freebsd.org/changeset/base/299862
Log: Reduce complexity of RSB by always using polling mode. Unfortunately gpiobus methods can be called with non-sleepable locks held. Reviewed by: mmel Modified: head/sys/arm/allwinner/aw_rsb.c head/sys/arm/allwinner/axp81x.c Modified: head/sys/arm/allwinner/aw_rsb.c ============================================================================== --- head/sys/arm/allwinner/aw_rsb.c Sun May 15 15:56:48 2016 (r299861) +++ head/sys/arm/allwinner/aw_rsb.c Sun May 15 16:43:47 2016 (r299862) @@ -38,7 +38,6 @@ __FBSDID("$FreeBSD$"); #include <sys/bus.h> #include <sys/rman.h> #include <sys/kernel.h> -#include <sys/proc.h> #include <sys/module.h> #include <machine/bus.h> @@ -100,7 +99,6 @@ static struct ofw_compat_data compat_dat static struct resource_spec rsb_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { SYS_RES_IRQ, 0, RF_ACTIVE }, { -1, 0 } }; @@ -125,12 +123,11 @@ static const struct { }; struct rsb_softc { - struct resource *res[2]; + struct resource *res; struct mtx mtx; clk_t clk; hwreset_t rst; device_t iicbus; - void *ih; int busy; uint32_t status; uint16_t cur_addr; @@ -141,8 +138,8 @@ struct rsb_softc { #define RSB_LOCK(sc) mtx_lock(&(sc)->mtx) #define RSB_UNLOCK(sc) mtx_unlock(&(sc)->mtx) #define RSB_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mtx, MA_OWNED) -#define RSB_READ(sc, reg) bus_read_4((sc)->res[0], (reg)) -#define RSB_WRITE(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val)) +#define RSB_READ(sc, reg) bus_read_4((sc)->res, (reg)) +#define RSB_WRITE(sc, reg, val) bus_write_4((sc)->res, (reg), (val)) static phandle_t rsb_get_node(device_t bus, device_t dev) @@ -202,34 +199,24 @@ static int rsb_start(device_t dev) { struct rsb_softc *sc; - int error, retry, polling; + int error, retry; sc = device_get_softc(dev); - polling = cold || !THREAD_CAN_SLEEP(); RSB_ASSERT_LOCKED(sc); - /* Enable interrupts */ - if (!polling) - RSB_WRITE(sc, RSB_INTE, INT_MASK); - /* Start the transfer */ RSB_WRITE(sc, RSB_CTRL, GLOBAL_INT_ENB | START_TRANS); /* Wait for transfer to complete */ - if (polling) { - error = ETIMEDOUT; - for (retry = RSB_I2C_TIMEOUT; retry > 0; retry--) { - sc->status |= RSB_READ(sc, RSB_INTS); - if ((sc->status & INT_TRANS_OVER) != 0) { - error = 0; - break; - } - DELAY((1000 * hz) / RSB_I2C_TIMEOUT); + error = ETIMEDOUT; + for (retry = RSB_I2C_TIMEOUT; retry > 0; retry--) { + sc->status |= RSB_READ(sc, RSB_INTS); + if ((sc->status & INT_TRANS_OVER) != 0) { + error = 0; + break; } - } else { - error = mtx_sleep(sc, &sc->mtx, 0, "i2ciowait", - RSB_I2C_TIMEOUT); + DELAY((1000 * hz) / RSB_I2C_TIMEOUT); } if (error == 0 && (sc->status & INT_TRANS_OVER) == 0) { device_printf(dev, "transfer error, status 0x%08x\n", @@ -237,9 +224,6 @@ rsb_start(device_t dev) error = EIO; } - /* Disable interrupts */ - RSB_WRITE(sc, RSB_INTE, 0); - return (error); } @@ -389,23 +373,6 @@ done: return (error); } -static void -rsb_intr(void *arg) -{ - struct rsb_softc *sc; - uint32_t val; - - sc = arg; - - RSB_LOCK(sc); - val = RSB_READ(sc, RSB_INTS); - RSB_WRITE(sc, RSB_INTS, val); - sc->status |= val; - if ((sc->status & INT_MASK) != 0) - wakeup(sc); - RSB_UNLOCK(sc); -} - static int rsb_probe(device_t dev) { @@ -443,19 +410,12 @@ rsb_attach(device_t dev) } } - if (bus_alloc_resources(dev, rsb_spec, sc->res) != 0) { + if (bus_alloc_resources(dev, rsb_spec, &sc->res) != 0) { device_printf(dev, "cannot allocate resources for device\n"); error = ENXIO; goto fail; } - error = bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE, - NULL, rsb_intr, sc, &sc->ih); - if (error != 0) { - device_printf(dev, "cannot setup interrupt handler\n"); - goto fail; - } - sc->iicbus = device_add_child(dev, "iicbus", -1); if (sc->iicbus == NULL) { device_printf(dev, "cannot add iicbus child device\n"); @@ -468,9 +428,7 @@ rsb_attach(device_t dev) return (0); fail: - if (sc->ih != NULL) - bus_teardown_intr(dev, sc->res[1], sc->ih); - bus_release_resources(dev, rsb_spec, sc->res); + bus_release_resources(dev, rsb_spec, &sc->res); if (sc->rst != NULL) hwreset_release(sc->rst); if (sc->clk != NULL) Modified: head/sys/arm/allwinner/axp81x.c ============================================================================== --- head/sys/arm/allwinner/axp81x.c Sun May 15 15:56:48 2016 (r299861) +++ head/sys/arm/allwinner/axp81x.c Sun May 15 16:43:47 2016 (r299862) @@ -40,7 +40,6 @@ __FBSDID("$FreeBSD$"); #include <sys/rman.h> #include <sys/kernel.h> #include <sys/reboot.h> -#include <sys/proc.h> #include <sys/gpio.h> #include <sys/module.h> #include <machine/bus.h> @@ -246,7 +245,6 @@ axp81x_gpio_pin_getflags(device_t dev, u sc = device_get_softc(dev); AXP_LOCK(sc); - THREAD_SLEEPING_OK(); error = axp81x_read(dev, axp81x_pins[pin].ctrl_reg, &data, 1); if (error == 0) { func = (data & AXP_GPIO_FUNC) >> AXP_GPIO_FUNC_SHIFT; @@ -258,7 +256,6 @@ axp81x_gpio_pin_getflags(device_t dev, u else *flags = 0; } - THREAD_NO_SLEEPING(); AXP_UNLOCK(sc); return (error); @@ -277,7 +274,6 @@ axp81x_gpio_pin_setflags(device_t dev, u sc = device_get_softc(dev); AXP_LOCK(sc); - THREAD_SLEEPING_OK(); error = axp81x_read(dev, axp81x_pins[pin].ctrl_reg, &data, 1); if (error == 0) { data &= ~AXP_GPIO_FUNC; @@ -287,7 +283,6 @@ axp81x_gpio_pin_setflags(device_t dev, u } error = axp81x_write(dev, axp81x_pins[pin].ctrl_reg, data); } - THREAD_NO_SLEEPING(); AXP_UNLOCK(sc); return (error); @@ -306,7 +301,6 @@ axp81x_gpio_pin_get(device_t dev, uint32 sc = device_get_softc(dev); AXP_LOCK(sc); - THREAD_SLEEPING_OK(); error = axp81x_read(dev, axp81x_pins[pin].ctrl_reg, &data, 1); if (error == 0) { func = (data & AXP_GPIO_FUNC) >> AXP_GPIO_FUNC_SHIFT; @@ -327,7 +321,6 @@ axp81x_gpio_pin_get(device_t dev, uint32 break; } } - THREAD_NO_SLEEPING(); AXP_UNLOCK(sc); return (error); @@ -346,7 +339,6 @@ axp81x_gpio_pin_set(device_t dev, uint32 sc = device_get_softc(dev); AXP_LOCK(sc); - THREAD_SLEEPING_OK(); error = axp81x_read(dev, axp81x_pins[pin].ctrl_reg, &data, 1); if (error == 0) { func = (data & AXP_GPIO_FUNC) >> AXP_GPIO_FUNC_SHIFT; @@ -363,7 +355,6 @@ axp81x_gpio_pin_set(device_t dev, uint32 } if (error == 0) error = axp81x_write(dev, axp81x_pins[pin].ctrl_reg, data); - THREAD_NO_SLEEPING(); AXP_UNLOCK(sc); return (error); @@ -383,7 +374,6 @@ axp81x_gpio_pin_toggle(device_t dev, uin sc = device_get_softc(dev); AXP_LOCK(sc); - THREAD_SLEEPING_OK(); error = axp81x_read(dev, axp81x_pins[pin].ctrl_reg, &data, 1); if (error == 0) { func = (data & AXP_GPIO_FUNC) >> AXP_GPIO_FUNC_SHIFT; @@ -403,7 +393,6 @@ axp81x_gpio_pin_toggle(device_t dev, uin } if (error == 0) error = axp81x_write(dev, axp81x_pins[pin].ctrl_reg, data); - THREAD_NO_SLEEPING(); AXP_UNLOCK(sc); return (error); _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"