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)
This commit is contained in:
parent
6f12163ca6
commit
9b394a3293
@ -155,6 +155,8 @@ at91_twi_detach(device_t dev)
|
|||||||
if (sc->iicbus && (rv = device_delete_child(dev, sc->iicbus)) != 0)
|
if (sc->iicbus && (rv = device_delete_child(dev, sc->iicbus)) != 0)
|
||||||
return (rv);
|
return (rv);
|
||||||
|
|
||||||
|
AT91_TWI_LOCK_DESTROY(sc);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,6 +213,7 @@ at91_twi_intr(void *xsc)
|
|||||||
status = RD4(sc, TWI_SR);
|
status = RD4(sc, TWI_SR);
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
return;
|
return;
|
||||||
|
AT91_TWI_LOCK(sc);
|
||||||
sc->flags |= status & (TWI_SR_OVRE | TWI_SR_UNRE | TWI_SR_NACK);
|
sc->flags |= status & (TWI_SR_OVRE | TWI_SR_UNRE | TWI_SR_NACK);
|
||||||
if (status & TWI_SR_RXRDY)
|
if (status & TWI_SR_RXRDY)
|
||||||
sc->flags |= TWI_SR_RXRDY;
|
sc->flags |= TWI_SR_RXRDY;
|
||||||
@ -220,6 +223,7 @@ at91_twi_intr(void *xsc)
|
|||||||
sc->flags |= TWI_SR_TXCOMP;
|
sc->flags |= TWI_SR_TXCOMP;
|
||||||
WR4(sc, TWI_IDR, status);
|
WR4(sc, TWI_IDR, status);
|
||||||
wakeup(sc);
|
wakeup(sc);
|
||||||
|
AT91_TWI_UNLOCK(sc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,6 +234,7 @@ at91_twi_wait(struct at91_twi_softc *sc, uint32_t bit)
|
|||||||
int counter = 100000;
|
int counter = 100000;
|
||||||
uint32_t sr;
|
uint32_t sr;
|
||||||
|
|
||||||
|
AT91_TWI_ASSERT_LOCKED(sc);
|
||||||
while (!((sr = RD4(sc, TWI_SR)) & bit) && counter-- > 0 &&
|
while (!((sr = RD4(sc, TWI_SR)) & bit) && counter-- > 0 &&
|
||||||
!(sr & TWI_SR_NACK))
|
!(sr & TWI_SR_NACK))
|
||||||
continue;
|
continue;
|
||||||
@ -247,6 +252,7 @@ at91_twi_rst_card(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
|
|||||||
int clk;
|
int clk;
|
||||||
|
|
||||||
sc = device_get_softc(dev);
|
sc = device_get_softc(dev);
|
||||||
|
AT91_TWI_LOCK(sc);
|
||||||
if (oldaddr)
|
if (oldaddr)
|
||||||
*oldaddr = sc->twi_addr;
|
*oldaddr = sc->twi_addr;
|
||||||
sc->twi_addr = 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_CR, TWI_CR_MSEN | TWI_CR_SVDIS);
|
||||||
WR4(sc, TWI_CWGR, sc->cwgr);
|
WR4(sc, TWI_CWGR, sc->cwgr);
|
||||||
printf("setting cwgr to %#x\n", sc->cwgr);
|
printf("setting cwgr to %#x\n", sc->cwgr);
|
||||||
|
AT91_TWI_UNLOCK(sc);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -106,9 +106,11 @@ ixpiic_getscl(device_t dev)
|
|||||||
struct ixpiic_softc *sc = ixpiic_sc;
|
struct ixpiic_softc *sc = ixpiic_sc;
|
||||||
uint32_t reg;
|
uint32_t reg;
|
||||||
|
|
||||||
|
mtx_lock(&Giant);
|
||||||
GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
|
GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
|
||||||
|
|
||||||
reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR);
|
reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR);
|
||||||
|
mtx_unlock(&Giant);
|
||||||
return (reg & GPIO_I2C_SCL_BIT);
|
return (reg & GPIO_I2C_SCL_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,9 +120,11 @@ ixpiic_getsda(device_t dev)
|
|||||||
struct ixpiic_softc *sc = ixpiic_sc;
|
struct ixpiic_softc *sc = ixpiic_sc;
|
||||||
uint32_t reg;
|
uint32_t reg;
|
||||||
|
|
||||||
|
mtx_lock(&Giant);
|
||||||
GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
|
GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
|
||||||
|
|
||||||
reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR);
|
reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR);
|
||||||
|
mtx_unlock(&Giant);
|
||||||
return (reg & GPIO_I2C_SDA_BIT);
|
return (reg & GPIO_I2C_SDA_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,11 +133,13 @@ ixpiic_setsda(device_t dev, char val)
|
|||||||
{
|
{
|
||||||
struct ixpiic_softc *sc = ixpiic_sc;
|
struct ixpiic_softc *sc = ixpiic_sc;
|
||||||
|
|
||||||
|
mtx_lock(&Giant);
|
||||||
GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SDA_BIT);
|
GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SDA_BIT);
|
||||||
if (val)
|
if (val)
|
||||||
GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
|
GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
|
||||||
else
|
else
|
||||||
GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
|
GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
|
||||||
|
mtx_unlock(&Giant);
|
||||||
DELAY(I2C_DELAY);
|
DELAY(I2C_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,11 +148,13 @@ ixpiic_setscl(device_t dev, char val)
|
|||||||
{
|
{
|
||||||
struct ixpiic_softc *sc = ixpiic_sc;
|
struct ixpiic_softc *sc = ixpiic_sc;
|
||||||
|
|
||||||
|
mtx_lock(&Giant);
|
||||||
GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SCL_BIT);
|
GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SCL_BIT);
|
||||||
if (val)
|
if (val)
|
||||||
GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
|
GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
|
||||||
else
|
else
|
||||||
GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
|
GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
|
||||||
|
mtx_unlock(&Giant);
|
||||||
DELAY(I2C_DELAY);
|
DELAY(I2C_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,3 +192,4 @@ static driver_t ixpiic_driver = {
|
|||||||
static devclass_t ixpiic_devclass;
|
static devclass_t ixpiic_devclass;
|
||||||
|
|
||||||
DRIVER_MODULE(ixpiic, ixp, ixpiic_driver, ixpiic_devclass, 0, 0);
|
DRIVER_MODULE(ixpiic, ixp, ixpiic_driver, ixpiic_devclass, 0, 0);
|
||||||
|
DRIVER_MODULE(iicbb, ixpiic, iicbb_driver, iicbb_devclass, 0, 0);
|
||||||
|
@ -356,6 +356,7 @@ bti2c_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DRIVER_MODULE(iicbb, bktr, iicbb_driver, iicbb_devclass, 0, 0);
|
||||||
DRIVER_MODULE(smbus, bktr, smbus_driver, smbus_devclass, 0, 0);
|
DRIVER_MODULE(smbus, bktr, smbus_driver, smbus_devclass, 0, 0);
|
||||||
|
|
||||||
#endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
|
#endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
|
||||||
|
@ -413,16 +413,7 @@ iicbb_read(device_t dev, char * buf, int len, int *read, int last, int delay)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
DRIVER_MODULE(iicbus, iicbb, iicbus_driver, iicbus_devclass, 0, 0);
|
||||||
* XXX This is lame. We need to have a base iicbb_bridge class that all these
|
|
||||||
* XXX derive from.
|
|
||||||
*/
|
|
||||||
DRIVER_MODULE(iicbb, bktr, iicbb_driver, iicbb_devclass, 0, 0);
|
|
||||||
DRIVER_MODULE(iicbb, ixpiic, iicbb_driver, iicbb_devclass, 0, 0);
|
|
||||||
DRIVER_MODULE(iicbb, lpbb, iicbb_driver, iicbb_devclass, 0, 0);
|
|
||||||
DRIVER_MODULE(iicbb, viapm, iicbb_driver, iicbb_devclass, 0, 0);
|
|
||||||
DRIVER_MODULE(iicbb, cxm_iic, iicbb_driver, iicbb_devclass, 0, 0);
|
|
||||||
DRIVER_MODULE(iicbb, at91_bbiic, iicbb_driver, iicbb_devclass, 0, 0);
|
|
||||||
|
|
||||||
MODULE_DEPEND(iicbb, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
|
MODULE_DEPEND(iicbb, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
|
||||||
MODULE_VERSION(iicbb, IICBB_MODVER);
|
MODULE_VERSION(iicbb, IICBB_MODVER);
|
||||||
|
@ -37,13 +37,15 @@ __FBSDID("$FreeBSD$");
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
|
||||||
#include <sys/bus.h>
|
#include <sys/bus.h>
|
||||||
#include <sys/conf.h>
|
#include <sys/conf.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
|
#include <sys/lock.h>
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#include <sys/module.h>
|
#include <sys/module.h>
|
||||||
|
#include <sys/mutex.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
|
|
||||||
#include <dev/ofw/ofw_bus.h>
|
#include <dev/ofw/ofw_bus.h>
|
||||||
@ -107,7 +109,7 @@ envctrl_attach(device_t dev)
|
|||||||
int rv = ENXIO;
|
int rv = ENXIO;
|
||||||
|
|
||||||
sc = DEVTOSOFTC(dev);
|
sc = DEVTOSOFTC(dev);
|
||||||
bzero(sc, sizeof(struct pcf_softc));
|
mtx_init(&sc->pcf_lock, device_get_nameunit(dev), "pcf", MTX_DEF);
|
||||||
|
|
||||||
/* IO port is mandatory */
|
/* IO port is mandatory */
|
||||||
sc->res_ioport = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
sc->res_ioport = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||||
@ -116,8 +118,6 @@ envctrl_attach(device_t dev)
|
|||||||
device_printf(dev, "cannot reserve I/O port range\n");
|
device_printf(dev, "cannot reserve I/O port range\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
sc->bt_ioport = rman_get_bustag(sc->res_ioport);
|
|
||||||
sc->bh_ioport = rman_get_bushandle(sc->res_ioport);
|
|
||||||
|
|
||||||
sc->pcf_flags = device_get_flags(dev);
|
sc->pcf_flags = device_get_flags(dev);
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ envctrl_attach(device_t dev)
|
|||||||
pcf_rst_card(dev, IIC_FASTEST, PCF_DEFAULT_ADDR, NULL);
|
pcf_rst_card(dev, IIC_FASTEST, PCF_DEFAULT_ADDR, NULL);
|
||||||
|
|
||||||
rv = bus_setup_intr(dev, sc->res_irq,
|
rv = bus_setup_intr(dev, sc->res_irq,
|
||||||
INTR_TYPE_NET /* | INTR_ENTROPY */,
|
INTR_TYPE_NET | INTR_MPSAFE /* | INTR_ENTROPY */,
|
||||||
NULL, pcf_intr, sc, &sc->intr_cookie);
|
NULL, pcf_intr, sc, &sc->intr_cookie);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
device_printf(dev, "could not setup IRQ\n");
|
device_printf(dev, "could not setup IRQ\n");
|
||||||
@ -158,6 +158,7 @@ error:
|
|||||||
bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_ioport,
|
bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_ioport,
|
||||||
sc->res_ioport);
|
sc->res_ioport);
|
||||||
}
|
}
|
||||||
|
mtx_destroy(&sc->pcf_lock);
|
||||||
return (rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,10 +182,12 @@ envctrl_detach(device_t dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_ioport, sc->res_ioport);
|
bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_ioport, sc->res_ioport);
|
||||||
|
mtx_destroy(&sc->pcf_lock);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DRIVER_MODULE(envctrl, ebus, envctrl_driver, envctrl_devclass, 0, 0);
|
DRIVER_MODULE(envctrl, ebus, envctrl_driver, envctrl_devclass, 0, 0);
|
||||||
|
DRIVER_MODULE(iicbus, envctrl, iicbus_driver, iicbus_devclass, 0, 0);
|
||||||
MODULE_DEPEND(envctrl, iicbus, PCF_MINVER, PCF_PREFVER, PCF_MAXVER);
|
MODULE_DEPEND(envctrl, iicbus, PCF_MINVER, PCF_PREFVER, PCF_MAXVER);
|
||||||
MODULE_VERSION(envctrl, PCF_MODVER);
|
MODULE_VERSION(envctrl, PCF_MODVER);
|
||||||
|
@ -29,10 +29,12 @@
|
|||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/bus.h>
|
||||||
|
#include <sys/lock.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/module.h>
|
#include <sys/module.h>
|
||||||
#include <sys/bus.h>
|
#include <sys/mutex.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
|
||||||
#include <machine/bus.h>
|
#include <machine/bus.h>
|
||||||
#include <machine/resource.h>
|
#include <machine/resource.h>
|
||||||
@ -48,16 +50,18 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
static int pcf_wait_byte(struct pcf_softc *pcf);
|
static int pcf_wait_byte(struct pcf_softc *pcf);
|
||||||
static int pcf_noack(struct pcf_softc *pcf, int timeout);
|
static int pcf_noack(struct pcf_softc *pcf, int timeout);
|
||||||
|
static void pcf_stop_locked(struct pcf_softc *pcf);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Polling mode for master operations wait for a new
|
* Polling mode for master operations wait for a new
|
||||||
* byte incomming or outgoing
|
* byte incoming or outgoing
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
pcf_wait_byte(struct pcf_softc *sc)
|
pcf_wait_byte(struct pcf_softc *sc)
|
||||||
{
|
{
|
||||||
int counter = TIMEOUT;
|
int counter = TIMEOUT;
|
||||||
|
|
||||||
|
PCF_ASSERT_LOCKED(sc);
|
||||||
while (counter--) {
|
while (counter--) {
|
||||||
|
|
||||||
if ((pcf_get_S1(sc) & PIN) == 0)
|
if ((pcf_get_S1(sc) & PIN) == 0)
|
||||||
@ -71,11 +75,11 @@ pcf_wait_byte(struct pcf_softc *sc)
|
|||||||
return (IIC_ETIMEOUT);
|
return (IIC_ETIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static void
|
||||||
pcf_stop(device_t dev)
|
pcf_stop_locked(struct pcf_softc *sc)
|
||||||
{
|
{
|
||||||
struct pcf_softc *sc = DEVTOSOFTC(dev);
|
|
||||||
|
|
||||||
|
PCF_ASSERT_LOCKED(sc);
|
||||||
#ifdef PCFDEBUG
|
#ifdef PCFDEBUG
|
||||||
device_printf(dev, " >> stop\n");
|
device_printf(dev, " >> stop\n");
|
||||||
#endif
|
#endif
|
||||||
@ -91,17 +95,15 @@ pcf_stop(device_t dev)
|
|||||||
|
|
||||||
sc->pcf_started = 0;
|
sc->pcf_started = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
int
|
|
||||||
pcf_noack(struct pcf_softc *sc, int timeout)
|
pcf_noack(struct pcf_softc *sc, int timeout)
|
||||||
{
|
{
|
||||||
int noack;
|
int noack;
|
||||||
int k = timeout/10;
|
int k = timeout/10;
|
||||||
|
|
||||||
|
PCF_ASSERT_LOCKED(sc);
|
||||||
do {
|
do {
|
||||||
noack = pcf_get_S1(sc) & LRB;
|
noack = pcf_get_S1(sc) & LRB;
|
||||||
if (!noack)
|
if (!noack)
|
||||||
@ -118,6 +120,7 @@ pcf_repeated_start(device_t dev, u_char slave, int timeout)
|
|||||||
struct pcf_softc *sc = DEVTOSOFTC(dev);
|
struct pcf_softc *sc = DEVTOSOFTC(dev);
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
|
PCF_LOCK(sc);
|
||||||
#ifdef PCFDEBUG
|
#ifdef PCFDEBUG
|
||||||
device_printf(dev, " >> repeated start for slave %#x\n",
|
device_printf(dev, " >> repeated start for slave %#x\n",
|
||||||
(unsigned)slave);
|
(unsigned)slave);
|
||||||
@ -142,10 +145,12 @@ pcf_repeated_start(device_t dev, u_char slave, int timeout)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PCF_UNLOCK(sc);
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
pcf_stop(dev);
|
pcf_stop_locked(sc);
|
||||||
|
PCF_UNLOCK(sc);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,6 +160,7 @@ pcf_start(device_t dev, u_char slave, int timeout)
|
|||||||
struct pcf_softc *sc = DEVTOSOFTC(dev);
|
struct pcf_softc *sc = DEVTOSOFTC(dev);
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
|
PCF_LOCK(sc);
|
||||||
#ifdef PCFDEBUG
|
#ifdef PCFDEBUG
|
||||||
device_printf(dev, " >> start for slave %#x\n", (unsigned)slave);
|
device_printf(dev, " >> start for slave %#x\n", (unsigned)slave);
|
||||||
#endif
|
#endif
|
||||||
@ -162,6 +168,7 @@ pcf_start(device_t dev, u_char slave, int timeout)
|
|||||||
#ifdef PCFDEBUG
|
#ifdef PCFDEBUG
|
||||||
printf("pcf: busy!\n");
|
printf("pcf: busy!\n");
|
||||||
#endif
|
#endif
|
||||||
|
PCF_UNLOCK(sc);
|
||||||
return (IIC_EBUSBSY);
|
return (IIC_EBUSBSY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,13 +194,30 @@ pcf_start(device_t dev, u_char slave, int timeout)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PCF_UNLOCK(sc);
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
pcf_stop(dev);
|
pcf_stop_locked(sc);
|
||||||
|
PCF_UNLOCK(sc);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pcf_stop(device_t dev)
|
||||||
|
{
|
||||||
|
struct pcf_softc *sc = DEVTOSOFTC(dev);
|
||||||
|
|
||||||
|
#ifdef PCFDEBUG
|
||||||
|
device_printf(dev, " >> stop\n");
|
||||||
|
#endif
|
||||||
|
PCF_LOCK(sc);
|
||||||
|
pcf_stop_locked(sc);
|
||||||
|
PCF_UNLOCK(sc);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pcf_intr(void *arg)
|
pcf_intr(void *arg)
|
||||||
{
|
{
|
||||||
@ -201,6 +225,7 @@ pcf_intr(void *arg)
|
|||||||
char data, status, addr;
|
char data, status, addr;
|
||||||
char error = 0;
|
char error = 0;
|
||||||
|
|
||||||
|
PCF_LOCK(sc);
|
||||||
status = pcf_get_S1(sc);
|
status = pcf_get_S1(sc);
|
||||||
|
|
||||||
if (status & PIN) {
|
if (status & PIN) {
|
||||||
@ -288,6 +313,7 @@ pcf_intr(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} while ((pcf_get_S1(sc) & PIN) == 0);
|
} while ((pcf_get_S1(sc) & PIN) == 0);
|
||||||
|
PCF_UNLOCK(sc);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -296,6 +322,7 @@ error:
|
|||||||
pcf_set_S1(sc, PIN|ESO|ENI|ACK);
|
pcf_set_S1(sc, PIN|ESO|ENI|ACK);
|
||||||
|
|
||||||
sc->pcf_slave_mode = SLAVE_RECEIVER;
|
sc->pcf_slave_mode = SLAVE_RECEIVER;
|
||||||
|
PCF_UNLOCK(sc);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -305,6 +332,7 @@ pcf_rst_card(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
|
|||||||
{
|
{
|
||||||
struct pcf_softc *sc = DEVTOSOFTC(dev);
|
struct pcf_softc *sc = DEVTOSOFTC(dev);
|
||||||
|
|
||||||
|
PCF_LOCK(sc);
|
||||||
if (oldaddr)
|
if (oldaddr)
|
||||||
*oldaddr = sc->pcf_addr;
|
*oldaddr = sc->pcf_addr;
|
||||||
|
|
||||||
@ -343,6 +371,7 @@ pcf_rst_card(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
|
|||||||
pcf_set_S1(sc, PIN|ESO|ENI|ACK);
|
pcf_set_S1(sc, PIN|ESO|ENI|ACK);
|
||||||
|
|
||||||
sc->pcf_slave_mode = SLAVE_RECEIVER;
|
sc->pcf_slave_mode = SLAVE_RECEIVER;
|
||||||
|
PCF_UNLOCK(sc);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -359,6 +388,7 @@ pcf_write(device_t dev, char *buf, int len, int *sent, int timeout /* us */)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bytes = 0;
|
bytes = 0;
|
||||||
|
PCF_LOCK(sc);
|
||||||
while (len) {
|
while (len) {
|
||||||
|
|
||||||
pcf_set_S0(sc, *buf++);
|
pcf_set_S0(sc, *buf++);
|
||||||
@ -379,6 +409,7 @@ pcf_write(device_t dev, char *buf, int len, int *sent, int timeout /* us */)
|
|||||||
|
|
||||||
error:
|
error:
|
||||||
*sent = bytes;
|
*sent = bytes;
|
||||||
|
PCF_UNLOCK(sc);
|
||||||
|
|
||||||
#ifdef PCFDEBUG
|
#ifdef PCFDEBUG
|
||||||
device_printf(dev, " >> %d bytes written (%d)\n", bytes, error);
|
device_printf(dev, " >> %d bytes written (%d)\n", bytes, error);
|
||||||
@ -399,6 +430,7 @@ pcf_read(device_t dev, char *buf, int len, int *read, int last,
|
|||||||
device_printf(dev, " << reading %d bytes\n", len);
|
device_printf(dev, " << reading %d bytes\n", len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
PCF_LOCK(sc);
|
||||||
/* trig the bus to get the first data byte in S0 */
|
/* trig the bus to get the first data byte in S0 */
|
||||||
if (len) {
|
if (len) {
|
||||||
if (len == 1 && last)
|
if (len == 1 && last)
|
||||||
@ -415,14 +447,14 @@ pcf_read(device_t dev, char *buf, int len, int *read, int last,
|
|||||||
|
|
||||||
/* wait for trigged byte */
|
/* wait for trigged byte */
|
||||||
if ((error = pcf_wait_byte(sc))) {
|
if ((error = pcf_wait_byte(sc))) {
|
||||||
pcf_stop(dev);
|
pcf_stop_locked(sc);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == 1 && last)
|
if (len == 1 && last)
|
||||||
/* ok, last data byte already in S0, no I2C activity
|
/* ok, last data byte already in S0, no I2C activity
|
||||||
* on next pcf_get_S0() */
|
* on next pcf_get_S0() */
|
||||||
pcf_stop(dev);
|
pcf_stop_locked(sc);
|
||||||
|
|
||||||
else if (len == 2 && last)
|
else if (len == 2 && last)
|
||||||
/* next trigged byte with no ack */
|
/* next trigged byte with no ack */
|
||||||
@ -437,6 +469,7 @@ pcf_read(device_t dev, char *buf, int len, int *read, int last,
|
|||||||
|
|
||||||
error:
|
error:
|
||||||
*read = bytes;
|
*read = bytes;
|
||||||
|
PCF_UNLOCK(sc);
|
||||||
|
|
||||||
#ifdef PCFDEBUG
|
#ifdef PCFDEBUG
|
||||||
device_printf(dev, " << %d bytes read (%d): %#x%s\n", bytes, error,
|
device_printf(dev, " << %d bytes read (%d): %#x%s\n", bytes, error,
|
||||||
|
@ -64,11 +64,13 @@ __FBSDID("$FreeBSD$");
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
|
||||||
#include <sys/bus.h>
|
#include <sys/bus.h>
|
||||||
|
#include <sys/lock.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/module.h>
|
#include <sys/module.h>
|
||||||
|
#include <sys/mutex.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
|
||||||
#include <dev/ofw/ofw_bus.h>
|
#include <dev/ofw/ofw_bus.h>
|
||||||
#include <dev/ofw/openfirm.h>
|
#include <dev/ofw/openfirm.h>
|
||||||
@ -142,7 +144,7 @@ pcf_ebus_attach(device_t dev)
|
|||||||
uint64_t own_addr;
|
uint64_t own_addr;
|
||||||
|
|
||||||
sc = DEVTOSOFTC(dev);
|
sc = DEVTOSOFTC(dev);
|
||||||
bzero(sc, sizeof(struct pcf_softc));
|
mtx_init(&sc->pcf_lock, device_get_nameunit(dev), "pcf", MTX_DEF);
|
||||||
|
|
||||||
/* get OFW node of the pcf */
|
/* get OFW node of the pcf */
|
||||||
if ((node = ofw_bus_get_node(dev)) <= 0) {
|
if ((node = ofw_bus_get_node(dev)) <= 0) {
|
||||||
@ -157,8 +159,6 @@ pcf_ebus_attach(device_t dev)
|
|||||||
device_printf(dev, "cannot reserve I/O port range\n");
|
device_printf(dev, "cannot reserve I/O port range\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
sc->bt_ioport = rman_get_bustag(sc->res_ioport);
|
|
||||||
sc->bh_ioport = rman_get_bushandle(sc->res_ioport);
|
|
||||||
|
|
||||||
sc->pcf_flags = device_get_flags(dev);
|
sc->pcf_flags = device_get_flags(dev);
|
||||||
|
|
||||||
@ -219,6 +219,7 @@ error:
|
|||||||
bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_ioport,
|
bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_ioport,
|
||||||
sc->res_ioport);
|
sc->res_ioport);
|
||||||
}
|
}
|
||||||
|
mtx_destroy(&sc->pcf_lock);
|
||||||
return (rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,6 +246,7 @@ pcf_ebus_detach(device_t dev)
|
|||||||
|
|
||||||
bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_ioport,
|
bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_ioport,
|
||||||
sc->res_ioport);
|
sc->res_ioport);
|
||||||
|
mtx_destroy(&sc->pcf_lock);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -36,11 +36,13 @@ __FBSDID("$FreeBSD$");
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
|
||||||
#include <sys/bus.h>
|
#include <sys/bus.h>
|
||||||
|
#include <sys/lock.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/module.h>
|
#include <sys/module.h>
|
||||||
|
#include <sys/mutex.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
|
||||||
#include <machine/bus.h>
|
#include <machine/bus.h>
|
||||||
#include <machine/resource.h>
|
#include <machine/resource.h>
|
||||||
@ -126,7 +128,7 @@ pcf_isa_attach(device_t dev)
|
|||||||
int rv = ENXIO;
|
int rv = ENXIO;
|
||||||
|
|
||||||
sc = DEVTOSOFTC(dev);
|
sc = DEVTOSOFTC(dev);
|
||||||
bzero(sc, sizeof(struct pcf_softc));
|
mtx_init(&sc->pcf_lock, device_get_nameunit(dev), "pcf", MTX_DEF);
|
||||||
|
|
||||||
/* IO port is mandatory */
|
/* IO port is mandatory */
|
||||||
sc->res_ioport = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
|
sc->res_ioport = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
|
||||||
@ -135,8 +137,6 @@ pcf_isa_attach(device_t dev)
|
|||||||
device_printf(dev, "cannot reserve I/O port range\n");
|
device_printf(dev, "cannot reserve I/O port range\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
sc->bt_ioport = rman_get_bustag(sc->res_ioport);
|
|
||||||
sc->bh_ioport = rman_get_bushandle(sc->res_ioport);
|
|
||||||
|
|
||||||
sc->pcf_flags = device_get_flags(dev);
|
sc->pcf_flags = device_get_flags(dev);
|
||||||
|
|
||||||
@ -179,6 +179,7 @@ error:
|
|||||||
bus_release_resource(dev, SYS_RES_IOPORT, sc->rid_ioport,
|
bus_release_resource(dev, SYS_RES_IOPORT, sc->rid_ioport,
|
||||||
sc->res_ioport);
|
sc->res_ioport);
|
||||||
}
|
}
|
||||||
|
mtx_destroy(&sc->pcf_lock);
|
||||||
return (rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,6 +203,7 @@ pcf_isa_detach(device_t dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bus_release_resource(dev, SYS_RES_IOPORT, sc->rid_ioport, sc->res_ioport);
|
bus_release_resource(dev, SYS_RES_IOPORT, sc->rid_ioport, sc->res_ioport);
|
||||||
|
mtx_destroy(&sc->pcf_lock);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,9 @@
|
|||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __PCFVAR_H__
|
||||||
|
#define __PCFVAR_H__
|
||||||
|
|
||||||
#define IO_PCFSIZE 2
|
#define IO_PCFSIZE 2
|
||||||
|
|
||||||
#define TIMEOUT 9999 /* XXX */
|
#define TIMEOUT 9999 /* XXX */
|
||||||
@ -63,19 +66,22 @@ struct pcf_softc {
|
|||||||
int pcf_slave_mode; /* receiver or transmitter */
|
int pcf_slave_mode; /* receiver or transmitter */
|
||||||
int pcf_started; /* 1 if start condition sent */
|
int pcf_started; /* 1 if start condition sent */
|
||||||
|
|
||||||
|
struct mtx pcf_lock;
|
||||||
device_t iicbus; /* the corresponding iicbus */
|
device_t iicbus; /* the corresponding iicbus */
|
||||||
|
|
||||||
/* Resource handling stuff. */
|
/* Resource handling stuff. */
|
||||||
struct resource *res_ioport;
|
struct resource *res_ioport;
|
||||||
int rid_ioport;
|
int rid_ioport;
|
||||||
bus_space_tag_t bt_ioport;
|
|
||||||
bus_space_handle_t bh_ioport;
|
|
||||||
struct resource *res_irq;
|
struct resource *res_irq;
|
||||||
int rid_irq;
|
int rid_irq;
|
||||||
void *intr_cookie;
|
void *intr_cookie;
|
||||||
};
|
};
|
||||||
#define DEVTOSOFTC(dev) ((struct pcf_softc *)device_get_softc(dev))
|
#define DEVTOSOFTC(dev) ((struct pcf_softc *)device_get_softc(dev))
|
||||||
|
|
||||||
|
#define PCF_LOCK(sc) mtx_lock(&(sc)->pcf_lock)
|
||||||
|
#define PCF_UNLOCK(sc) mtx_unlock(&(sc)->pcf_lock)
|
||||||
|
#define PCF_ASSERT_LOCKED(sc) mtx_assert(&(sc)->pcf_lock, MA_OWNED)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PCF8584 datasheet : when operate at 8 MHz or more, a minimun time of
|
* PCF8584 datasheet : when operate at 8 MHz or more, a minimun time of
|
||||||
* 6 clocks cycles must be left between two consecutives access
|
* 6 clocks cycles must be left between two consecutives access
|
||||||
@ -92,7 +98,7 @@ static __inline void
|
|||||||
pcf_set_S0(struct pcf_softc *sc, int data)
|
pcf_set_S0(struct pcf_softc *sc, int data)
|
||||||
{
|
{
|
||||||
|
|
||||||
bus_space_write_1(sc->bt_ioport, sc->bh_ioport, 0, data);
|
bus_write_1(sc->res_ioport, 0, data);
|
||||||
pcf_nops();
|
pcf_nops();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +106,7 @@ static __inline void
|
|||||||
pcf_set_S1(struct pcf_softc *sc, int data)
|
pcf_set_S1(struct pcf_softc *sc, int data)
|
||||||
{
|
{
|
||||||
|
|
||||||
bus_space_write_1(sc->bt_ioport, sc->bh_ioport, 1, data);
|
bus_write_1(sc->res_ioport, 1, data);
|
||||||
pcf_nops();
|
pcf_nops();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +115,7 @@ pcf_get_S0(struct pcf_softc *sc)
|
|||||||
{
|
{
|
||||||
char data;
|
char data;
|
||||||
|
|
||||||
data = bus_space_read_1(sc->bt_ioport, sc->bh_ioport, 0);
|
data = bus_read_1(sc->res_ioport, 0);
|
||||||
pcf_nops();
|
pcf_nops();
|
||||||
|
|
||||||
return (data);
|
return (data);
|
||||||
@ -120,7 +126,7 @@ pcf_get_S1(struct pcf_softc *sc)
|
|||||||
{
|
{
|
||||||
char data;
|
char data;
|
||||||
|
|
||||||
data = bus_space_read_1(sc->bt_ioport, sc->bh_ioport, 1);
|
data = bus_read_1(sc->res_ioport, 1);
|
||||||
pcf_nops();
|
pcf_nops();
|
||||||
|
|
||||||
return (data);
|
return (data);
|
||||||
@ -138,3 +144,5 @@ extern driver_intr_t pcf_intr;
|
|||||||
#define PCF_MINVER 1
|
#define PCF_MINVER 1
|
||||||
#define PCF_MAXVER 1
|
#define PCF_MAXVER 1
|
||||||
#define PCF_PREFVER PCF_MODVER
|
#define PCF_PREFVER PCF_MODVER
|
||||||
|
|
||||||
|
#endif /* !__PCFVAR_H__ */
|
||||||
|
@ -36,10 +36,12 @@ __FBSDID("$FreeBSD$");
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/kernel.h>
|
|
||||||
#include <sys/systm.h>
|
|
||||||
#include <sys/module.h>
|
|
||||||
#include <sys/bus.h>
|
#include <sys/bus.h>
|
||||||
|
#include <sys/lock.h>
|
||||||
|
#include <sys/kernel.h>
|
||||||
|
#include <sys/module.h>
|
||||||
|
#include <sys/mutex.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
|
|
||||||
|
|
||||||
@ -101,12 +103,16 @@ lpbb_callback(device_t dev, int index, caddr_t *data)
|
|||||||
case IIC_REQUEST_BUS:
|
case IIC_REQUEST_BUS:
|
||||||
/* request the ppbus */
|
/* request the ppbus */
|
||||||
how = *(int *)data;
|
how = *(int *)data;
|
||||||
|
mtx_lock(&Giant);
|
||||||
error = ppb_request_bus(ppbus, dev, how);
|
error = ppb_request_bus(ppbus, dev, how);
|
||||||
|
mtx_unlock(&Giant);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IIC_RELEASE_BUS:
|
case IIC_RELEASE_BUS:
|
||||||
/* release the ppbus */
|
/* release the ppbus */
|
||||||
|
mtx_lock(&Giant);
|
||||||
error = ppb_release_bus(ppbus, dev);
|
error = ppb_release_bus(ppbus, dev);
|
||||||
|
mtx_unlock(&Giant);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -123,37 +129,56 @@ lpbb_callback(device_t dev, int index, caddr_t *data)
|
|||||||
#define ALIM 0x20
|
#define ALIM 0x20
|
||||||
#define I2CKEY 0x50
|
#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);
|
device_t ppbus = device_get_parent(dev);
|
||||||
|
|
||||||
if(val==0)
|
mtx_lock(&Giant);
|
||||||
|
if (val == 0)
|
||||||
ppb_wdtr(ppbus, (u_char)SDA_out);
|
ppb_wdtr(ppbus, (u_char)SDA_out);
|
||||||
else
|
else
|
||||||
ppb_wdtr(ppbus, (u_char)~SDA_out);
|
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);
|
device_t ppbus = device_get_parent(dev);
|
||||||
|
|
||||||
if(val==0)
|
mtx_lock(&Giant);
|
||||||
ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus)&~SCL_out));
|
if (val == 0)
|
||||||
|
ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus) & ~SCL_out));
|
||||||
else
|
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);
|
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);
|
device_t ppbus = device_get_parent(dev);
|
||||||
|
|
||||||
|
mtx_lock(&Giant);
|
||||||
if (ppb_request_bus(ppbus, dev, PPB_DONTWAIT)) {
|
if (ppb_request_bus(ppbus, dev, PPB_DONTWAIT)) {
|
||||||
device_printf(dev, "can't allocate ppbus\n");
|
device_printf(dev, "can't allocate ppbus\n");
|
||||||
return (0);
|
return (0);
|
||||||
@ -193,6 +219,7 @@ lpbb_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr)
|
|||||||
lpbb_setscl(dev, 1);
|
lpbb_setscl(dev, 1);
|
||||||
|
|
||||||
ppb_release_bus(ppbus, dev);
|
ppb_release_bus(ppbus, dev);
|
||||||
|
mtx_unlock(&Giant);
|
||||||
|
|
||||||
return (IIC_ENOADDR);
|
return (IIC_ENOADDR);
|
||||||
}
|
}
|
||||||
@ -226,6 +253,7 @@ static driver_t lpbb_driver = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DRIVER_MODULE(lpbb, ppbus, lpbb_driver, lpbb_devclass, 0, 0);
|
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, ppbus, 1, 1, 1);
|
||||||
MODULE_DEPEND(lpbb, iicbb, IICBB_MINVER, IICBB_PREFVER, IICBB_MAXVER);
|
MODULE_DEPEND(lpbb, iicbb, IICBB_MINVER, IICBB_PREFVER, IICBB_MAXVER);
|
||||||
MODULE_VERSION(lpbb, 1);
|
MODULE_VERSION(lpbb, 1);
|
||||||
|
@ -1009,6 +1009,7 @@ static driver_t viapropm_driver = {
|
|||||||
|
|
||||||
DRIVER_MODULE(viapm, pci, viapm_driver, viapm_devclass, 0, 0);
|
DRIVER_MODULE(viapm, pci, viapm_driver, viapm_devclass, 0, 0);
|
||||||
DRIVER_MODULE(viapropm, pci, viapropm_driver, viapropm_devclass, 0, 0);
|
DRIVER_MODULE(viapropm, pci, viapropm_driver, viapropm_devclass, 0, 0);
|
||||||
|
DRIVER_MODULE(iicbb, viapm, iicbb_driver, iicbb_devclass, 0, 0);
|
||||||
DRIVER_MODULE(smbus, viapropm, smbus_driver, smbus_devclass, 0, 0);
|
DRIVER_MODULE(smbus, viapropm, smbus_driver, smbus_devclass, 0, 0);
|
||||||
|
|
||||||
MODULE_DEPEND(viapm, pci, 1, 1, 1);
|
MODULE_DEPEND(viapm, pci, 1, 1, 1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user