summaryrefslogtreecommitdiffstats
path: root/sys/dev/ppbus
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/dev/ppbus
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/dev/ppbus')
-rw-r--r--sys/dev/ppbus/lpbb.c54
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);
OpenPOWER on IntegriCloud