Provide a mutex around the read/modify/write of the IXP425_GPIO_*
registers. Giant was used in some places, but not all.
This commit is contained in:
parent
c3adda9fc3
commit
a0ba8fd51c
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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__);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user