git: 6f9d0f02e72c - main - jh7110_gpio: handle preset high/low

From: Mitchell Horne <mhorne_at_FreeBSD.org>
Date: Wed, 30 Sep 2026 19:28:25 UTC
The branch main has been updated by mhorne:

URL: https://cgit.FreeBSD.org/src/commit/?id=6f9d0f02e72cdcf64af6e0a034af4d4f065b26f8

commit 6f9d0f02e72cdcf64af6e0a034af4d4f065b26f8
Author:     Mitchell Horne <mhorne@FreeBSD.org>
AuthorDate: 2026-09-30 19:23:03 +0000
Commit:     Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2026-09-30 19:26:04 +0000

    jh7110_gpio: handle preset high/low
    
    Take action in the presence of the GPIO_PIN_PRESET_LOW/HIGH flags. This
    part of the GPIO interface seems to be unused, but is trivially
    implemented in our driver.
    
    Reviewed by:    Brian Scott <bscott@bunyatech.com.au>
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D59991
---
 sys/riscv/starfive/jh7110_gpio.c | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/sys/riscv/starfive/jh7110_gpio.c b/sys/riscv/starfive/jh7110_gpio.c
index fdf40e5c147d..22e435a8d146 100644
--- a/sys/riscv/starfive/jh7110_gpio.c
+++ b/sys/riscv/starfive/jh7110_gpio.c
@@ -92,6 +92,7 @@ static struct resource_spec jh7110_gpio_spec[] = {
 
 #define	JH7110_GPIO_LOCK(_sc)		mtx_lock(&(_sc)->mtx)
 #define	JH7110_GPIO_UNLOCK(_sc)		mtx_unlock(&(_sc)->mtx)
+#define	JH7110_GPIO_ASSERT_LOCKED(_sc)	mtx_assert(&(_sc)->mtx, MA_OWNED);
 
 #define	RD4(sc, reg)			bus_read_4((sc)->res, (reg))
 #define	WR4(sc, reg, val)		bus_write_4((sc)->res, (reg), (val))
@@ -145,11 +146,26 @@ jh7110_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *val)
 	return (0);
 }
 
+static void
+jh7110_gpio_pin_set_locked(struct jh7110_gpio_softc *sc, uint32_t pin,
+    uint32_t val)
+{
+	uint32_t reg;
+
+	JH7110_GPIO_ASSERT_LOCKED(sc);
+	MPASS(pin <= sc->maxpin);
+
+	reg = RD4(sc, sc->doutcfg + GPIO_RW_OFFSET(pin));
+	reg &= ~(DATA_OUT_MASK << GPIO_SHIFT(pin));
+	if (val != 0)
+		reg |= 0x1 << GPIO_SHIFT(pin);
+	WR4(sc, sc->doutcfg + GPIO_RW_OFFSET(pin), reg);
+}
+
 static int
 jh7110_gpio_pin_set(device_t dev, uint32_t pin, uint32_t val)
 {
 	struct jh7110_gpio_softc *sc;
-	uint32_t reg;
 
 	sc = device_get_softc(dev);
 
@@ -157,11 +173,7 @@ jh7110_gpio_pin_set(device_t dev, uint32_t pin, uint32_t val)
 		return (EINVAL);
 
 	JH7110_GPIO_LOCK(sc);
-	reg = RD4(sc, sc->doutcfg + GPIO_RW_OFFSET(pin));
-	reg &= ~(DATA_OUT_MASK << GPIO_SHIFT(pin));
-	if (val != 0)
-		reg |= 0x1 << GPIO_SHIFT(pin);
-	WR4(sc, sc->doutcfg + GPIO_RW_OFFSET(pin), reg);
+	jh7110_gpio_pin_set_locked(sc, pin, val);
 	JH7110_GPIO_UNLOCK(sc);
 
 	return (0);
@@ -303,6 +315,13 @@ jh7110_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
 		WR4(sc, sc->iomuxcfg + PAD_OFFSET(pin), reg);
 	}
 
+	/* Handle preset values. */
+	if ((flags & GPIO_PIN_PRESET_LOW) != 0) {
+		jh7110_gpio_pin_set_locked(sc, pin, 0);
+	} else if ((flags & GPIO_PIN_PRESET_HIGH) != 0) {
+		jh7110_gpio_pin_set_locked(sc, pin, 1);
+	}
+
 	JH7110_GPIO_UNLOCK(sc);
 
 	return (0);