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