diff options
author | jhb <jhb@FreeBSD.org> | 2008-08-04 20:46:15 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2008-08-04 20:46:15 +0000 |
commit | 9b394a3293bfa4397c24c6649034b411994dbb72 (patch) | |
tree | 2a244ae80de29ad3e4b277353b095b09dc4a9aba /sys/dev/ppbus | |
parent | 6f12163ca676979b992a474aab9c999d288f57ed (diff) | |
download | FreeBSD-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/dev/ppbus')
-rw-r--r-- | sys/dev/ppbus/lpbb.c | 54 |
1 files changed, 41 insertions, 13 deletions
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 <sys/param.h> +#include <sys/bus.h> +#include <sys/lock.h> #include <sys/kernel.h> -#include <sys/systm.h> #include <sys/module.h> -#include <sys/bus.h> +#include <sys/mutex.h> +#include <sys/systm.h> #include <sys/uio.h> @@ -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); |