From 9b394a3293bfa4397c24c6649034b411994dbb72 Mon Sep 17 00:00:00 2001 From: jhb Date: Mon, 4 Aug 2008 20:46:15 +0000 Subject: 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) --- sys/dev/ppbus/lpbb.c | 54 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 13 deletions(-) (limited to 'sys/dev/ppbus') diff --git a/sys/dev/ppbus/lpbb.c b/sys/dev/ppbus/lpbb.c index 07a2f21..51d3398 100644 --- a/sys/dev/ppbus/lpbb.c +++ b/sys/dev/ppbus/lpbb.c @@ -36,10 +36,12 @@ __FBSDID("$FreeBSD$"); */ #include +#include +#include #include -#include #include -#include +#include +#include #include @@ -101,12 +103,16 @@ lpbb_callback(device_t dev, int index, caddr_t *data) case IIC_REQUEST_BUS: /* request the ppbus */ how = *(int *)data; + mtx_lock(&Giant); error = ppb_request_bus(ppbus, dev, how); + mtx_unlock(&Giant); break; case IIC_RELEASE_BUS: /* release the ppbus */ + mtx_lock(&Giant); error = ppb_release_bus(ppbus, dev); + mtx_unlock(&Giant); break; default: @@ -123,37 +129,56 @@ lpbb_callback(device_t dev, int index, caddr_t *data) #define ALIM 0x20 #define I2CKEY 0x50 -static int lpbb_getscl(device_t dev) +static int +lpbb_getscl(device_t dev) { - return ((ppb_rstr(device_get_parent(dev)) & SCL_in) == SCL_in); + int rval; + + mtx_lock(&Giant); + rval = ((ppb_rstr(device_get_parent(dev)) & SCL_in) == SCL_in); + mtx_unlock(&Giant); + return (rval); } -static int lpbb_getsda(device_t dev) +static int +lpbb_getsda(device_t dev) { - return ((ppb_rstr(device_get_parent(dev)) & SDA_in) == SDA_in); + int rval; + + mtx_lock(&Giant); + rval = ((ppb_rstr(device_get_parent(dev)) & SDA_in) == SDA_in); + mtx_unlock(&Giant); + return (rval); } -static void lpbb_setsda(device_t dev, char val) +static void +lpbb_setsda(device_t dev, char val) { device_t ppbus = device_get_parent(dev); - if(val==0) + mtx_lock(&Giant); + if (val == 0) ppb_wdtr(ppbus, (u_char)SDA_out); else ppb_wdtr(ppbus, (u_char)~SDA_out); + mtx_unlock(&Giant); } -static void lpbb_setscl(device_t dev, unsigned char val) +static void +lpbb_setscl(device_t dev, unsigned char val) { device_t ppbus = device_get_parent(dev); - if(val==0) - ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus)&~SCL_out)); + mtx_lock(&Giant); + if (val == 0) + ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus) & ~SCL_out)); else - ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus)|SCL_out)); + ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus) | SCL_out)); + mtx_unlock(&Giant); } -static int lpbb_detect(device_t dev) +static int +lpbb_detect(device_t dev) { device_t ppbus = device_get_parent(dev); @@ -183,6 +208,7 @@ lpbb_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr) { device_t ppbus = device_get_parent(dev); + mtx_lock(&Giant); if (ppb_request_bus(ppbus, dev, PPB_DONTWAIT)) { device_printf(dev, "can't allocate ppbus\n"); return (0); @@ -193,6 +219,7 @@ lpbb_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr) lpbb_setscl(dev, 1); ppb_release_bus(ppbus, dev); + mtx_unlock(&Giant); return (IIC_ENOADDR); } @@ -226,6 +253,7 @@ static driver_t lpbb_driver = { }; DRIVER_MODULE(lpbb, ppbus, lpbb_driver, lpbb_devclass, 0, 0); +DRIVER_MODULE(iicbb, lpbb, iicbb_driver, iicbb_devclass, 0, 0); MODULE_DEPEND(lpbb, ppbus, 1, 1, 1); MODULE_DEPEND(lpbb, iicbb, IICBB_MINVER, IICBB_PREFVER, IICBB_MAXVER); MODULE_VERSION(lpbb, 1); -- cgit v1.1