nctgpio: Populate the cache earlier

Reviewed by: imp
Pull Request: https://github.com/freebsd/freebsd-src/pull/719
This commit is contained in:
Stéphane Rochoy 2023-07-01 11:19:44 -06:00 committed by Warner Losh
parent 350b7c3570
commit f03a7e5276

View file

@ -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);