diff options
author | thompsa <thompsa@FreeBSD.org> | 2010-11-14 20:41:22 +0000 |
---|---|---|
committer | thompsa <thompsa@FreeBSD.org> | 2010-11-14 20:41:22 +0000 |
commit | 62bef117d8fce7e2833ac5356272bc3543cc55dd (patch) | |
tree | 7631c455293f5f98c0ce3c86189d463b4129a35a /sys/arm/xscale/ixp425 | |
parent | 02778a6df67bca2283e2b9d79262fe0692dab2d4 (diff) | |
download | FreeBSD-src-62bef117d8fce7e2833ac5356272bc3543cc55dd.zip FreeBSD-src-62bef117d8fce7e2833ac5356272bc3543cc55dd.tar.gz |
Provide a mutex around the read/modify/write of the IXP425_GPIO_*
registers. Giant was used in some places, but not all.
Diffstat (limited to 'sys/arm/xscale/ixp425')
-rw-r--r-- | sys/arm/xscale/ixp425/avila_gpio.c | 42 | ||||
-rw-r--r-- | sys/arm/xscale/ixp425/avila_led.c | 2 | ||||
-rw-r--r-- | sys/arm/xscale/ixp425/cambria_gpio.c | 12 | ||||
-rw-r--r-- | sys/arm/xscale/ixp425/ixp425.c | 5 | ||||
-rw-r--r-- | sys/arm/xscale/ixp425/ixp425_iic.c | 16 | ||||
-rw-r--r-- | sys/arm/xscale/ixp425/ixp425var.h | 3 |
6 files changed, 35 insertions, 45 deletions
diff --git a/sys/arm/xscale/ixp425/avila_gpio.c b/sys/arm/xscale/ixp425/avila_gpio.c index 82103a1..cb73001 100644 --- a/sys/arm/xscale/ixp425/avila_gpio.c +++ b/sys/arm/xscale/ixp425/avila_gpio.c @@ -58,13 +58,8 @@ __FBSDID("$FreeBSD$"); #define GPIO_CLEAR_BITS(sc, reg, bits) \ GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, (reg)) & ~(bits)) -#define GPIO_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) -#define GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) -#define GPIO_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) - struct avila_gpio_softc { device_t sc_dev; - struct mtx sc_mtx; bus_space_tag_t sc_iot; bus_space_handle_t sc_gpio_ioh; uint32_t sc_valid; @@ -148,12 +143,12 @@ avila_gpio_pin_configure(struct avila_gpio_softc *sc, struct gpio_pin *pin, uint32_t mask; mask = 1 << pin->gp_pin; - GPIO_LOCK(sc); /* * Manage input/output */ if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { + IXP4XX_GPIO_LOCK(sc); pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT); if (flags & GPIO_PIN_OUTPUT) { pin->gp_flags |= GPIO_PIN_OUTPUT; @@ -163,9 +158,8 @@ avila_gpio_pin_configure(struct avila_gpio_softc *sc, struct gpio_pin *pin, pin->gp_flags |= GPIO_PIN_INPUT; GPIO_SET_BITS(sc, IXP425_GPIO_GPOER, mask); } + IXP4XX_GPIO_UNLOCK(sc); } - - GPIO_UNLOCK(sc); } static int @@ -184,10 +178,7 @@ avila_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & (1 << pin))) return (EINVAL); - GPIO_LOCK(sc); *caps = sc->sc_pins[pin].gp_caps; - GPIO_UNLOCK(sc); - return (0); } @@ -199,11 +190,11 @@ avila_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & (1 << pin))) return (EINVAL); - GPIO_LOCK(sc); + IXP4XX_GPIO_LOCK(sc); /* refresh since we do not own all the pins */ sc->sc_pins[pin].gp_flags = avila_gpio_pin_flags(sc, pin); *flags = sc->sc_pins[pin].gp_flags; - GPIO_UNLOCK(sc); + IXP4XX_GPIO_UNLOCK(sc); return (0); } @@ -216,10 +207,7 @@ avila_gpio_pin_getname(device_t dev, uint32_t pin, char *name) if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & (1 << pin))) return (EINVAL); - GPIO_LOCK(sc); memcpy(name, sc->sc_pins[pin].gp_name, GPIOMAXNAME); - GPIO_UNLOCK(sc); - return (0); } @@ -254,12 +242,12 @@ avila_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & mask)) return (EINVAL); - GPIO_LOCK(sc); + IXP4XX_GPIO_LOCK(sc); if (value) GPIO_SET_BITS(sc, IXP425_GPIO_GPOUTR, mask); else GPIO_CLEAR_BITS(sc, IXP425_GPIO_GPOUTR, mask); - GPIO_UNLOCK(sc); + IXP4XX_GPIO_UNLOCK(sc); return (0); } @@ -272,9 +260,9 @@ avila_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & (1 << pin))) return (EINVAL); - GPIO_LOCK(sc); + IXP4XX_GPIO_LOCK(sc); *val = (GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR) & (1 << pin)) ? 1 : 0; - GPIO_UNLOCK(sc); + IXP4XX_GPIO_UNLOCK(sc); return (0); } @@ -289,13 +277,13 @@ avila_gpio_pin_toggle(device_t dev, uint32_t pin) if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & mask)) return (EINVAL); - GPIO_LOCK(sc); - res = (GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR) & mask) ? 1 : 0; + IXP4XX_GPIO_LOCK(sc); + res = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR) & mask; if (res) GPIO_CLEAR_BITS(sc, IXP425_GPIO_GPOUTR, mask); else GPIO_SET_BITS(sc, IXP425_GPIO_GPOUTR, mask); - GPIO_UNLOCK(sc); + IXP4XX_GPIO_UNLOCK(sc); return (0); } @@ -320,9 +308,6 @@ avila_gpio_attach(device_t dev) sc->sc_iot = sa->sc_iot; sc->sc_gpio_ioh = sa->sc_gpio_ioh; - mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_DEF); - for (i = 0; i < N(avila_gpio_pins); i++) { struct avila_gpio_pin *p = &avila_gpio_pins[i]; @@ -342,14 +327,9 @@ avila_gpio_attach(device_t dev) static int avila_gpio_detach(device_t dev) { - struct avila_gpio_softc *sc = device_get_softc(dev); - - KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized")); bus_generic_detach(dev); - mtx_destroy(&sc->sc_mtx); - return(0); } diff --git a/sys/arm/xscale/ixp425/avila_led.c b/sys/arm/xscale/ixp425/avila_led.c index 1d1553b..ed41782 100644 --- a/sys/arm/xscale/ixp425/avila_led.c +++ b/sys/arm/xscale/ixp425/avila_led.c @@ -52,12 +52,14 @@ led_func(void *arg, int onoff) struct led_avila_softc *sc = arg; uint32_t reg; + IXP4XX_GPIO_LOCK(); reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR); if (onoff) reg &= ~GPIO_LED_STATUS_BIT; else reg |= GPIO_LED_STATUS_BIT; GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg); + IXP4XX_GPIO_UNLOCK(); } static int diff --git a/sys/arm/xscale/ixp425/cambria_gpio.c b/sys/arm/xscale/ixp425/cambria_gpio.c index 89b07d8..509cdc3 100644 --- a/sys/arm/xscale/ixp425/cambria_gpio.c +++ b/sys/arm/xscale/ixp425/cambria_gpio.c @@ -133,11 +133,11 @@ i2c_getsda(struct cambria_gpio_softc *sc) { uint32_t reg; - mtx_lock(&Giant); + IXP4XX_GPIO_LOCK(); GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR); - mtx_unlock(&Giant); + IXP4XX_GPIO_UNLOCK(); return (reg & GPIO_I2C_SDA_BIT); } @@ -145,13 +145,13 @@ static void i2c_setsda(struct cambria_gpio_softc *sc, int val) { - mtx_lock(&Giant); + IXP4XX_GPIO_LOCK(); GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SDA_BIT); if (val) GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); else GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); - mtx_unlock(&Giant); + IXP4XX_GPIO_UNLOCK(); DELAY(I2C_DELAY); } @@ -159,13 +159,13 @@ static void i2c_setscl(struct cambria_gpio_softc *sc, int val) { - mtx_lock(&Giant); + IXP4XX_GPIO_LOCK(); GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SCL_BIT); if (val) GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT); else GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT); - mtx_unlock(&Giant); + IXP4XX_GPIO_UNLOCK(); DELAY(I2C_DELAY); } diff --git a/sys/arm/xscale/ixp425/ixp425.c b/sys/arm/xscale/ixp425/ixp425.c index 9b11b43..78d2042 100644 --- a/sys/arm/xscale/ixp425/ixp425.c +++ b/sys/arm/xscale/ixp425/ixp425.c @@ -66,6 +66,8 @@ uint32_t intr_steer2 = 0; struct ixp425_softc *ixp425_softc = NULL; +struct mtx ixp425_gpio_mtx; + static int ixp425_probe(device_t); static void ixp425_identify(driver_t *, device_t); static int ixp425_attach(device_t); @@ -164,6 +166,7 @@ ixp425_set_gpio(struct ixp425_softc *sc, int pin, int type) { uint32_t gpiotr = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(pin)); + IXP4XX_GPIO_LOCK(); /* clear interrupt type */ GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(pin), gpiotr &~ GPIO_TYPE(pin, GPIO_TYPE_MASK)); @@ -176,6 +179,7 @@ ixp425_set_gpio(struct ixp425_softc *sc, int pin, int type) /* configure gpio line as an input */ GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOER, GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOER) | (1<<pin)); + IXP4XX_GPIO_UNLOCK(); } static __inline void @@ -313,6 +317,7 @@ ixp425_attach(device_t dev) } arm_post_filter = ixp425_post_filter; + mtx_init(&ixp425_gpio_mtx, "gpio", NULL, MTX_DEF); if (bus_space_map(sc->sc_iot, IXP425_GPIO_HWBASE, IXP425_GPIO_SIZE, 0, &sc->sc_gpio_ioh)) panic("%s: unable to map GPIO registers", __func__); diff --git a/sys/arm/xscale/ixp425/ixp425_iic.c b/sys/arm/xscale/ixp425/ixp425_iic.c index bb7d47f..342a6a5 100644 --- a/sys/arm/xscale/ixp425/ixp425_iic.c +++ b/sys/arm/xscale/ixp425/ixp425_iic.c @@ -106,11 +106,11 @@ ixpiic_getscl(device_t dev) struct ixpiic_softc *sc = ixpiic_sc; uint32_t reg; - mtx_lock(&Giant); + IXP4XX_GPIO_LOCK(); GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT); reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR); - mtx_unlock(&Giant); + IXP4XX_GPIO_UNLOCK(); return (reg & GPIO_I2C_SCL_BIT); } @@ -120,11 +120,11 @@ ixpiic_getsda(device_t dev) struct ixpiic_softc *sc = ixpiic_sc; uint32_t reg; - mtx_lock(&Giant); + IXP4XX_GPIO_LOCK(); GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR); - mtx_unlock(&Giant); + IXP4XX_GPIO_UNLOCK(); return (reg & GPIO_I2C_SDA_BIT); } @@ -133,13 +133,13 @@ ixpiic_setsda(device_t dev, int val) { struct ixpiic_softc *sc = ixpiic_sc; - mtx_lock(&Giant); + IXP4XX_GPIO_LOCK(); GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SDA_BIT); if (val) GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); else GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); - mtx_unlock(&Giant); + IXP4XX_GPIO_UNLOCK(); DELAY(I2C_DELAY); } @@ -148,13 +148,13 @@ ixpiic_setscl(device_t dev, int val) { struct ixpiic_softc *sc = ixpiic_sc; - mtx_lock(&Giant); + IXP4XX_GPIO_LOCK(); GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SCL_BIT); if (val) GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT); else GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT); - mtx_unlock(&Giant); + IXP4XX_GPIO_UNLOCK(); DELAY(I2C_DELAY); } diff --git a/sys/arm/xscale/ixp425/ixp425var.h b/sys/arm/xscale/ixp425/ixp425var.h index 0f22b91..5d90e10 100644 --- a/sys/arm/xscale/ixp425/ixp425var.h +++ b/sys/arm/xscale/ixp425/ixp425var.h @@ -93,6 +93,9 @@ struct ixppcib_softc { bus_space_write_4(sc->sc_iot, sc->sc_gpio_ioh, reg, data) #define GPIO_CONF_READ_4(sc, reg) \ bus_space_read_4(sc->sc_iot, sc->sc_gpio_ioh, reg) +#define IXP4XX_GPIO_LOCK() mtx_lock(&ixp425_gpio_mtx) +#define IXP4XX_GPIO_UNLOCK() mtx_unlock(&ixp425_gpio_mtx) +extern struct mtx ixp425_gpio_mtx; extern struct bus_space ixp425_bs_tag; extern struct bus_space ixp425_a4x_bs_tag; |