Handle correctly iicbus request/release mechanism. Add iicbus allocation
to the general purpose i/o iic(4) driver.
This commit is contained in:
parent
b54915a02a
commit
a05e5f3178
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: iic.c,v 1.5 1998/12/07 21:58:16 archie Exp $
|
||||
* $Id: iic.c,v 1.6 1999/01/09 18:08:24 nsouch Exp $
|
||||
*
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
@ -35,6 +35,7 @@
|
||||
#include <sys/buf.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
|
||||
@ -169,12 +170,17 @@ iicwrite(dev_t dev, struct uio * uio, int ioflag)
|
||||
if (sc->sc_count == 0)
|
||||
return (EINVAL);
|
||||
|
||||
if ((error = iicbus_request_bus(device_get_parent(iicdev), iicdev, IIC_DONTWAIT)))
|
||||
return (error);
|
||||
|
||||
count = min(uio->uio_resid, BUFSIZE);
|
||||
uiomove(sc->sc_buffer, count, uio);
|
||||
|
||||
error = iicbus_block_write(device_get_parent(iicdev), sc->sc_addr,
|
||||
sc->sc_buffer, count, &sent);
|
||||
|
||||
iicbus_release_bus(device_get_parent(iicdev), iicdev);
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
@ -192,6 +198,9 @@ iicread(dev_t dev, struct uio * uio, int ioflag)
|
||||
if (sc->sc_count == 0)
|
||||
return (EINVAL);
|
||||
|
||||
if ((error = iicbus_request_bus(device_get_parent(iicdev), iicdev, IIC_DONTWAIT)))
|
||||
return (error);
|
||||
|
||||
/* max amount of data to read */
|
||||
len = min(uio->uio_resid, BUFSIZE);
|
||||
|
||||
@ -202,6 +211,8 @@ iicread(dev_t dev, struct uio * uio, int ioflag)
|
||||
if (bufsize > uio->uio_resid)
|
||||
panic("%s: too much data read!", __FUNCTION__);
|
||||
|
||||
iicbus_release_bus(device_get_parent(iicdev), iicdev);
|
||||
|
||||
return (uiomove(sc->sc_inbuf, bufsize, uio));
|
||||
}
|
||||
|
||||
@ -217,6 +228,11 @@ iicioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
|
||||
if (!sc)
|
||||
return (EINVAL);
|
||||
|
||||
if ((error = iicbus_request_bus(device_get_parent(iicdev), iicdev,
|
||||
(flags & O_NONBLOCK) ? IIC_DONTWAIT :
|
||||
(IIC_WAIT | IIC_INTR))))
|
||||
return (error);
|
||||
|
||||
switch (cmd) {
|
||||
case I2CSTART:
|
||||
error = iicbus_start(parent, s->slave, 0);
|
||||
@ -242,6 +258,8 @@ iicioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
|
||||
error = ENODEV;
|
||||
}
|
||||
|
||||
iicbus_release_bus(device_get_parent(iicdev), iicdev);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: iiconf.c,v 1.5 1999/01/28 15:59:15 roger Exp $
|
||||
* $Id: iiconf.c,v 1.6 1999/02/06 10:56:09 roger Exp $
|
||||
*
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
@ -104,16 +104,12 @@ iicbus_request_bus(device_t bus, device_t dev, int how)
|
||||
int s, error = 0;
|
||||
|
||||
/* first, ask the underlying layers if the request is ok */
|
||||
do {
|
||||
error = IICBUS_CALLBACK(device_get_parent(bus),
|
||||
IIC_REQUEST_BUS, (caddr_t)&how);
|
||||
if (error)
|
||||
error = iicbus_poll(sc, how);
|
||||
} while (error);
|
||||
error = IICBUS_CALLBACK(device_get_parent(bus), IIC_REQUEST_BUS,
|
||||
(caddr_t)&how);
|
||||
|
||||
while (!error) {
|
||||
s = splhigh();
|
||||
if (sc->owner) {
|
||||
if (sc->owner && sc->owner != dev) {
|
||||
splx(s);
|
||||
|
||||
error = iicbus_poll(sc, how);
|
||||
@ -123,6 +119,11 @@ iicbus_request_bus(device_t bus, device_t dev, int how)
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* free any allocated resource */
|
||||
if (error)
|
||||
IICBUS_CALLBACK(device_get_parent(bus), IIC_RELEASE_BUS,
|
||||
(caddr_t)&how);
|
||||
}
|
||||
|
||||
return (error);
|
||||
|
Loading…
Reference in New Issue
Block a user