git: f03a7e52769e - main - nctgpio: Populate the cache earlier
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 01 Jul 2023 17:20:49 UTC
The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=f03a7e52769e7d5cf706021d4b21953e5bd945a4 commit f03a7e52769e7d5cf706021d4b21953e5bd945a4 Author: Stéphane Rochoy <stephane.rochoy@stormshield.eu> AuthorDate: 2023-07-01 17:19:44 +0000 Commit: Warner Losh <imp@FreeBSD.org> CommitDate: 2023-07-01 17:19:54 +0000 nctgpio: Populate the cache earlier Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/719 --- sys/dev/nctgpio/nctgpio.c | 53 +++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/sys/dev/nctgpio/nctgpio.c b/sys/dev/nctgpio/nctgpio.c index fc3de033968f..07208e0fbd90 100644 --- a/sys/dev/nctgpio/nctgpio.c +++ b/sys/dev/nctgpio/nctgpio.c @@ -1200,6 +1200,32 @@ nct_attach(device_t dev) pin_num = 0; sc->npins = 0; for (g = 0, gp = sc->nctdevp->groups; g < sc->nctdevp->ngroups; g++, gp++) { + + sc->grpmap[gp->grpnum] = gp; + + /* + * Caching input values is meaningless as an input can be changed at any + * time by an external agent. But outputs are controlled by this + * driver, so it can cache their state. Also, the hardware remembers + * the output state of a pin when the pin is switched to input mode and + * then back to output mode. So, the cache stays valid. + * The only problem is with pins that are in input mode at the attach + * time. For them the output state is not known until it is set by the + * driver for the first time. + * 'out' and 'out_known' bits form a tri-state output cache: + * |-----+-----------+---------| + * | out | out_known | cache | + * |-----+-----------+---------| + * | X | 0 | invalid | + * | 0 | 1 | 0 | + * | 1 | 1 | 1 | + * |-----+-----------+---------| + */ + sc->cache.inv[gp->grpnum] = nct_read_reg(sc, REG_INV, gp->grpnum); + sc->cache.ior[gp->grpnum] = nct_read_reg(sc, REG_IOR, gp->grpnum); + sc->cache.out[gp->grpnum] = nct_read_reg(sc, REG_DAT, gp->grpnum); + sc->cache.out_known[gp->grpnum] = ~sc->cache.ior[gp->grpnum]; + sc->npins += gp->npins; for (i = 0; i < gp->npins; i++, pin_num++) { struct gpio_pin *pin; @@ -1208,8 +1234,6 @@ nct_attach(device_t dev) sc->pinmap[pin_num].grpnum = gp->grpnum; sc->pinmap[pin_num].bit = gp->pinbits[i]; - sc->grpmap[gp->grpnum] = gp; - pin = &sc->pins[pin_num]; pin->gp_pin = pin_num; pin->gp_caps = gp->caps; @@ -1234,31 +1258,6 @@ nct_attach(device_t dev) } NCT_VERBOSE_PRINTF(dev, "%d pins available\n", sc->npins); - /* - * Caching input values is meaningless as an input can be changed at any - * time by an external agent. But outputs are controlled by this - * driver, so it can cache their state. Also, the hardware remembers - * the output state of a pin when the pin is switched to input mode and - * then back to output mode. So, the cache stays valid. - * The only problem is with pins that are in input mode at the attach - * time. For them the output state is not known until it is set by the - * driver for the first time. - * 'out' and 'out_known' bits form a tri-state output cache: - * |-----+-----------+---------| - * | out | out_known | cache | - * |-----+-----------+---------| - * | X | 0 | invalid | - * | 0 | 1 | 0 | - * | 1 | 1 | 1 | - * |-----+-----------+---------| - */ - for (g = 0, gp = sc->nctdevp->groups; g < sc->nctdevp->ngroups; g++, gp++) { - sc->cache.inv[gp->grpnum] = nct_read_reg(sc, REG_INV, gp->grpnum); - sc->cache.ior[gp->grpnum] = nct_read_reg(sc, REG_IOR, gp->grpnum); - sc->cache.out[gp->grpnum] = nct_read_reg(sc, REG_DAT, gp->grpnum); - sc->cache.out_known[gp->grpnum] = ~sc->cache.ior[gp->grpnum]; - } - GPIO_UNLOCK(sc); sc->busdev = gpiobus_attach_bus(dev);