summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2008-08-04 20:46:15 +0000
committerjhb <jhb@FreeBSD.org>2008-08-04 20:46:15 +0000
commit9b394a3293bfa4397c24c6649034b411994dbb72 (patch)
tree2a244ae80de29ad3e4b277353b095b09dc4a9aba /sys/arm
parent6f12163ca676979b992a474aab9c999d288f57ed (diff)
downloadFreeBSD-src-9b394a3293bfa4397c24c6649034b411994dbb72.zip
FreeBSD-src-9b394a3293bfa4397c24c6649034b411994dbb72.tar.gz
Add locking to the various iicbus(4) bridge drivers:
- Just grab Giant in the ixp425_iic(4) driver since this driver uses a shared address/data register window pair to access the actual I2C registers. None of the other ixp425 drivers lock access to these shared address/data registers yet and that would need to be done before this could use any meaningful locking. - Add locking to the interrupt handler and 'iicbus_reset' methods of the at91_twi(4) driver. - Add locking to the pcf(4) driver. Other pcf(4) fixes include: - Don't needlessly zero the softc. - Use bus_foo rather than bus_space_foo and remove bus space tag and handle from softc. - The lpbb(4) driver just grabs Giant for now. This will be refined later when ppbus(4) is locked. - As was done with smbus earlier, move the DRIVER_MODULE() lines to match the bus driver (either iicbus or iicbb) to the bridge driver into the bridge drivers. Tested by: sam (arm/ixp425)
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/at91/at91_twi.c7
-rw-r--r--sys/arm/xscale/ixp425/ixp425_iic.c9
2 files changed, 16 insertions, 0 deletions
diff --git a/sys/arm/at91/at91_twi.c b/sys/arm/at91/at91_twi.c
index 0d8a2d4..ec05d14 100644
--- a/sys/arm/at91/at91_twi.c
+++ b/sys/arm/at91/at91_twi.c
@@ -155,6 +155,8 @@ at91_twi_detach(device_t dev)
if (sc->iicbus && (rv = device_delete_child(dev, sc->iicbus)) != 0)
return (rv);
+ AT91_TWI_LOCK_DESTROY(sc);
+
return (0);
}
@@ -211,6 +213,7 @@ at91_twi_intr(void *xsc)
status = RD4(sc, TWI_SR);
if (status == 0)
return;
+ AT91_TWI_LOCK(sc);
sc->flags |= status & (TWI_SR_OVRE | TWI_SR_UNRE | TWI_SR_NACK);
if (status & TWI_SR_RXRDY)
sc->flags |= TWI_SR_RXRDY;
@@ -220,6 +223,7 @@ at91_twi_intr(void *xsc)
sc->flags |= TWI_SR_TXCOMP;
WR4(sc, TWI_IDR, status);
wakeup(sc);
+ AT91_TWI_UNLOCK(sc);
return;
}
@@ -230,6 +234,7 @@ at91_twi_wait(struct at91_twi_softc *sc, uint32_t bit)
int counter = 100000;
uint32_t sr;
+ AT91_TWI_ASSERT_LOCKED(sc);
while (!((sr = RD4(sc, TWI_SR)) & bit) && counter-- > 0 &&
!(sr & TWI_SR_NACK))
continue;
@@ -247,6 +252,7 @@ at91_twi_rst_card(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
int clk;
sc = device_get_softc(dev);
+ AT91_TWI_LOCK(sc);
if (oldaddr)
*oldaddr = sc->twi_addr;
sc->twi_addr = addr;
@@ -275,6 +281,7 @@ at91_twi_rst_card(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
WR4(sc, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS);
WR4(sc, TWI_CWGR, sc->cwgr);
printf("setting cwgr to %#x\n", sc->cwgr);
+ AT91_TWI_UNLOCK(sc);
return 0;
}
diff --git a/sys/arm/xscale/ixp425/ixp425_iic.c b/sys/arm/xscale/ixp425/ixp425_iic.c
index ecc889f..38a86a6 100644
--- a/sys/arm/xscale/ixp425/ixp425_iic.c
+++ b/sys/arm/xscale/ixp425/ixp425_iic.c
@@ -106,9 +106,11 @@ ixpiic_getscl(device_t dev)
struct ixpiic_softc *sc = ixpiic_sc;
uint32_t reg;
+ mtx_lock(&Giant);
GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR);
+ mtx_unlock(&Giant);
return (reg & GPIO_I2C_SCL_BIT);
}
@@ -118,9 +120,11 @@ ixpiic_getsda(device_t dev)
struct ixpiic_softc *sc = ixpiic_sc;
uint32_t reg;
+ mtx_lock(&Giant);
GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR);
+ mtx_unlock(&Giant);
return (reg & GPIO_I2C_SDA_BIT);
}
@@ -129,11 +133,13 @@ ixpiic_setsda(device_t dev, char val)
{
struct ixpiic_softc *sc = ixpiic_sc;
+ mtx_lock(&Giant);
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);
DELAY(I2C_DELAY);
}
@@ -142,11 +148,13 @@ ixpiic_setscl(device_t dev, char val)
{
struct ixpiic_softc *sc = ixpiic_sc;
+ mtx_lock(&Giant);
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);
DELAY(I2C_DELAY);
}
@@ -184,3 +192,4 @@ static driver_t ixpiic_driver = {
static devclass_t ixpiic_devclass;
DRIVER_MODULE(ixpiic, ixp, ixpiic_driver, ixpiic_devclass, 0, 0);
+DRIVER_MODULE(iicbb, ixpiic, iicbb_driver, iicbb_devclass, 0, 0);
OpenPOWER on IntegriCloud