Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 17 May 2021 13:47:57 GMT
From:      Justin Hibbits <jhibbits@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: b2ee069e8cf7 - main - Fix locking in qoriq_gpio
Message-ID:  <202105171347.14HDlvhx051625@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by jhibbits:

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

commit b2ee069e8cf73ea91388dbbc9061af01109c774a
Author:     Justin Hibbits <jhibbits@FreeBSD.org>
AuthorDate: 2021-05-17 13:22:30 +0000
Commit:     Justin Hibbits <jhibbits@FreeBSD.org>
CommitDate: 2021-05-17 13:46:45 +0000

    Fix locking in qoriq_gpio
    
    qoriq_gpio_pin_setflags() locks the device mutex, as does
    qoriq_gpio_map_gpios(), causing a recursion on non-recursive lock.  This
    was missed during testing for 16e549ebe.
---
 sys/dev/gpio/qoriq_gpio.c | 36 ++++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/sys/dev/gpio/qoriq_gpio.c b/sys/dev/gpio/qoriq_gpio.c
index 82bd6cd9a72b..dc4813e07b8e 100644
--- a/sys/dev/gpio/qoriq_gpio.c
+++ b/sys/dev/gpio/qoriq_gpio.c
@@ -131,23 +131,15 @@ qoriq_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
 	return (0);
 }
 
-/* Set flags for the pin. */
 static int
-qoriq_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+qoriq_gpio_pin_configure(device_t dev, uint32_t pin, uint32_t flags)
 {
-	struct qoriq_gpio_softc *sc = device_get_softc(dev);
+	struct qoriq_gpio_softc *sc;
 	uint32_t reg;
 
-	if (!VALID_PIN(pin))
-		return (EINVAL);
-
-	if ((flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) ==
-	    (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
-		return (EINVAL);
+	sc = device_get_softc(dev);
 
-	GPIO_LOCK(sc);
 	if ((flags & sc->sc_pins[pin].gp_caps) != flags) {
-		GPIO_UNLOCK(sc);
 		return (EINVAL);
 	}
 
@@ -168,6 +160,26 @@ qoriq_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
 		bus_write_4(sc->sc_mem, GPIO_GPODR, reg);
 	}
 	sc->sc_pins[pin].gp_flags = flags;
+
+	return (0);
+}
+
+/* Set flags for the pin. */
+static int
+qoriq_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+{
+	struct qoriq_gpio_softc *sc = device_get_softc(dev);
+	uint32_t ret;
+
+	if (!VALID_PIN(pin))
+		return (EINVAL);
+
+	if ((flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) ==
+	    (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	ret = qoriq_gpio_pin_configure(dev, pin, flags);
 	GPIO_UNLOCK(sc);
 	return (0);
 }
@@ -356,7 +368,7 @@ qoriq_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
 
 	sc = device_get_softc(bus);
 	GPIO_LOCK(sc);
-	err = qoriq_gpio_pin_setflags(bus, gpios[0], gpios[1]);
+	err = qoriq_gpio_pin_configure(bus, gpios[0], gpios[1]);
 	GPIO_UNLOCK(sc);
 
 	if (err == 0) {



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