Author: ian
Date: Wed Jan  8 22:06:31 2020
New Revision: 356519
URL: https://svnweb.freebsd.org/changeset/base/356519

Log:
  Ensure any reserved gpio pins get released if an early exit is taken
  from the attach function.

Modified:
  head/sys/dev/iicbus/mux/iic_gpiomux.c

Modified: head/sys/dev/iicbus/mux/iic_gpiomux.c
==============================================================================
--- head/sys/dev/iicbus/mux/iic_gpiomux.c       Wed Jan  8 21:22:44 2020        
(r356518)
+++ head/sys/dev/iicbus/mux/iic_gpiomux.c       Wed Jan  8 22:06:31 2020        
(r356519)
@@ -119,6 +119,15 @@ gpiomux_probe(device_t dev)
        return (rv);
 }
 
+static void
+gpiomux_release_pins(struct gpiomux_softc *sc)
+{
+       int i;
+
+       for (i = 0; i < sc->numpins; ++i)
+               gpio_pin_release(sc->pins[i]);
+}
+
 static int
 gpiomux_attach(device_t dev)
 {
@@ -145,13 +154,16 @@ gpiomux_attach(device_t dev)
        sc->numpins = i;
        if (sc->numpins == 0) {
                device_printf(dev, "cannot acquire pins listed in mux-gpios\n");
-               return ((err == 0) ? ENXIO : err);
+               if (err == 0)
+                       err = ENXIO;
+               goto errexit;
        }
        numchannels = 1u << sc->numpins;
        if (numchannels > IICMUX_MAX_BUSES) {
                device_printf(dev, "too many mux-gpios pins for max %d buses\n",
                    IICMUX_MAX_BUSES);
-               return (EINVAL);
+               err = EINVAL;
+               goto errexit;
        }
 
        /*
@@ -163,13 +175,15 @@ gpiomux_attach(device_t dev)
        len = OF_getencprop(node, "i2c-parent", &propval, sizeof(propval));
        if (len != sizeof(propval)) {
                device_printf(dev, "cannot obtain i2c-parent property\n");
-               return (ENXIO);
+               err = ENXIO;
+               goto errexit;
        }
        busdev = OF_device_from_xref((phandle_t)propval);
        if (busdev == NULL) {
                device_printf(dev,
                    "cannot find device referenced by i2c-parent property\n");
-               return (ENXIO);
+               err = ENXIO;
+               goto errexit;
        }
        device_printf(dev, "upstream bus is %s\n", device_get_nameunit(busdev));
 
@@ -202,6 +216,11 @@ gpiomux_attach(device_t dev)
        if ((err = iicmux_attach(dev, busdev, numchannels)) == 0)
                bus_generic_attach(dev);
 
+errexit:
+
+       if (err != 0)
+               gpiomux_release_pins(sc);
+
        return (err);
 }
 
@@ -209,13 +228,12 @@ static int
 gpiomux_detach(device_t dev)
 {
        struct gpiomux_softc *sc = device_get_softc(dev);
-       int err, i;
+       int err;
 
        if ((err = iicmux_detach(dev)) != 0)
                return (err);
 
-       for (i = 0; i < sc->numpins; ++i)
-               gpio_pin_release(sc->pins[i]);
+       gpiomux_release_pins(sc);
 
        return (0);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to