Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 Jan 2020 22:06:31 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r356519 - head/sys/dev/iicbus/mux
Message-ID:  <202001082206.008M6VsZ043677@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202001082206.008M6VsZ043677>