summaryrefslogtreecommitdiffstats
path: root/sys/arm/freescale
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2016-04-07 19:51:27 +0000
committerian <ian@FreeBSD.org>2016-04-07 19:51:27 +0000
commit4a670a48704efbbc8611576a75f4987f92800b2a (patch)
tree8e52b3518c1a24f9ca23f3d364f359edee257998 /sys/arm/freescale
parentd1312255dfda198688cc3865c5da8b0bf08f5672 (diff)
downloadFreeBSD-src-4a670a48704efbbc8611576a75f4987f92800b2a.zip
FreeBSD-src-4a670a48704efbbc8611576a75f4987f92800b2a.tar.gz
Remove unecessary locking, mostly from places where a read is done of a
value that can't ever be in an inconsistant intermediate state even when some other thread is in the middle of writing the value/register. Locking of the hardware remains in the few places that do r-m-w operations. Locking of metadata access is restricted to places using memcpy or sprintf to modify the metadata.
Diffstat (limited to 'sys/arm/freescale')
-rw-r--r--sys/arm/freescale/imx/imx_gpio.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/sys/arm/freescale/imx/imx_gpio.c b/sys/arm/freescale/imx/imx_gpio.c
index 96b54fb..df0f2ad 100644
--- a/sys/arm/freescale/imx/imx_gpio.c
+++ b/sys/arm/freescale/imx/imx_gpio.c
@@ -451,22 +451,27 @@ static void
imx51_gpio_pin_configure(struct imx51_gpio_softc *sc, struct gpio_pin *pin,
unsigned int flags)
{
+ u_int newflags;
mtx_lock_spin(&sc->sc_mtx);
/*
- * Manage input/output
+ * Manage input/output; other flags not supported yet.
+ *
+ * Note that changes to pin->gp_flags must be acccumulated in newflags
+ * and stored with a single writeback to gp_flags at the end, to enable
+ * unlocked reads of that value elsewhere.
*/
- if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
- pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
+ if (flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
+ newflags = pin->gp_flags & ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT);
if (flags & GPIO_PIN_OUTPUT) {
- pin->gp_flags |= GPIO_PIN_OUTPUT;
+ newflags |= GPIO_PIN_OUTPUT;
SET4(sc, IMX_GPIO_OE_REG, (1U << pin->gp_pin));
- }
- else {
- pin->gp_flags |= GPIO_PIN_INPUT;
+ } else {
+ newflags |= GPIO_PIN_INPUT;
CLEAR4(sc, IMX_GPIO_OE_REG, (1U << pin->gp_pin));
}
+ pin->gp_flags = newflags;
}
mtx_unlock_spin(&sc->sc_mtx);
@@ -503,9 +508,7 @@ imx51_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
if (pin >= sc->gpio_npins)
return (EINVAL);
- mtx_lock_spin(&sc->sc_mtx);
*caps = sc->gpio_pins[pin].gp_caps;
- mtx_unlock_spin(&sc->sc_mtx);
return (0);
}
@@ -520,9 +523,7 @@ imx51_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
if (pin >= sc->gpio_npins)
return (EINVAL);
- mtx_lock_spin(&sc->sc_mtx);
*flags = sc->gpio_pins[pin].gp_flags;
- mtx_unlock_spin(&sc->sc_mtx);
return (0);
}
@@ -588,9 +589,7 @@ imx51_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
if (pin >= sc->gpio_npins)
return (EINVAL);
- mtx_lock_spin(&sc->sc_mtx);
*val = (READ4(sc, IMX_GPIO_DR_REG) >> pin) & 1;
- mtx_unlock_spin(&sc->sc_mtx);
return (0);
}
OpenPOWER on IntegriCloud