Make gpio(4) release the device reference that device_lookup() takes. OK?
Index: dev/gpio/gpio.c =================================================================== RCS file: src/sys/dev/gpio/gpio.c,v retrieving revision 1.16 diff -u -p -r1.16 gpio.c --- dev/gpio/gpio.c 6 Apr 2022 18:59:28 -0000 1.16 +++ dev/gpio/gpio.c 10 Apr 2022 14:45:40 -0000 @@ -53,6 +53,7 @@ int gpio_detach(struct device *, int); int gpio_search(struct device *, void *, void *); int gpio_print(void *, const char *); int gpio_pinbyname(struct gpio_softc *, char *gp_name); +int gpio_ioctl(struct gpio_softc *, u_long, caddr_t, int); const struct cfattach gpio_ca = { sizeof (struct gpio_softc), @@ -249,16 +250,20 @@ int gpioopen(dev_t dev, int flag, int mode, struct proc *p) { struct gpio_softc *sc; + int error = 0; sc = (struct gpio_softc *)device_lookup(&gpio_cd, minor(dev)); if (sc == NULL) return (ENXIO); if (sc->sc_opened) - return (EBUSY); - sc->sc_opened = 1; + error = EBUSY; + else + sc->sc_opened = 1; - return (0); + device_unref(&sc->sc_dev); + + return (error); } int @@ -272,6 +277,8 @@ gpioclose(dev_t dev, int flag, int mode, sc->sc_opened = 0; + device_unref(&sc->sc_dev); + return (0); } @@ -287,9 +294,8 @@ gpio_pinbyname(struct gpio_softc *sc, ch } int -gpioioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) +gpio_ioctl(struct gpio_softc *sc, u_long cmd, caddr_t data, int flag) { - struct gpio_softc *sc; gpio_chipset_tag_t gc; struct gpio_info *info; struct gpio_pin_op *op; @@ -301,10 +307,6 @@ gpioioctl(dev_t dev, u_long cmd, caddr_t struct device *dv; int pin, value, flags, npins, found; - sc = (struct gpio_softc *)device_lookup(&gpio_cd, minor(dev)); - if (sc == NULL) - return (ENXIO); - gc = sc->sc_gc; switch (cmd) { @@ -520,4 +522,21 @@ gpioioctl(dev_t dev, u_long cmd, caddr_t } return (0); +} + +int +gpioioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + struct gpio_softc *sc; + int error; + + sc = (struct gpio_softc *)device_lookup(&gpio_cd, minor(dev)); + if (sc == NULL) + return (ENXIO); + + error = gpio_ioctl(sc, cmd, data, flag); + + device_unref(&sc->sc_dev); + + return (error); }