Author: ian
Date: Thu Apr  7 19:51:27 2016
New Revision: 297684
URL: https://svnweb.freebsd.org/changeset/base/297684

Log:
  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.

Modified:
  head/sys/arm/freescale/imx/imx_gpio.c

Modified: head/sys/arm/freescale/imx/imx_gpio.c
==============================================================================
--- head/sys/arm/freescale/imx/imx_gpio.c       Thu Apr  7 19:17:47 2016        
(r297683)
+++ head/sys/arm/freescale/imx/imx_gpio.c       Thu Apr  7 19:51:27 2016        
(r297684)
@@ -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, uin
        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, ui
        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_
        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);
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to