svn commit: r356519 - head/sys/dev/iicbus/mux
Ian Lepore
ian at FreeBSD.org
Wed Jan 8 22:06:31 UTC 2020
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);
}
More information about the svn-src-all
mailing list