Allow drivers to provide their own read/write register functions. While
here, sprinkle KASSERTs to verify that the i2c lock is held where it should be.
This commit is contained in:
parent
7274112a01
commit
36a27f76f7
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: gttwsi_core.c,v 1.2 2014/11/23 13:37:27 jmcneill Exp $ */
|
/* $NetBSD: gttwsi_core.c,v 1.3 2017/10/29 14:59:05 jmcneill Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008 Eiji Kawauchi.
|
* Copyright (c) 2008 Eiji Kawauchi.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: gttwsi_core.c,v 1.2 2014/11/23 13:37:27 jmcneill Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: gttwsi_core.c,v 1.3 2017/10/29 14:59:05 jmcneill Exp $");
|
||||||
#include "locators.h"
|
#include "locators.h"
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
@ -94,7 +94,7 @@ static int gttwsi_write_byte(void *v, uint8_t val, int flags);
|
||||||
static int gttwsi_wait(struct gttwsi_softc *, uint32_t, uint32_t, int);
|
static int gttwsi_wait(struct gttwsi_softc *, uint32_t, uint32_t, int);
|
||||||
|
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
gttwsi_read_4(struct gttwsi_softc *sc, uint32_t reg)
|
gttwsi_default_read_4(struct gttwsi_softc *sc, uint32_t reg)
|
||||||
{
|
{
|
||||||
uint32_t val = bus_space_read_4(sc->sc_bust, sc->sc_bush, reg);
|
uint32_t val = bus_space_read_4(sc->sc_bust, sc->sc_bush, reg);
|
||||||
#ifdef TWSI_DEBUG
|
#ifdef TWSI_DEBUG
|
||||||
|
@ -106,7 +106,7 @@ gttwsi_read_4(struct gttwsi_softc *sc, uint32_t reg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
gttwsi_write_4(struct gttwsi_softc *sc, uint32_t reg, uint32_t val)
|
gttwsi_default_write_4(struct gttwsi_softc *sc, uint32_t reg, uint32_t val)
|
||||||
{
|
{
|
||||||
bus_space_write_4(sc->sc_bust, sc->sc_bush, reg, val);
|
bus_space_write_4(sc->sc_bust, sc->sc_bush, reg, val);
|
||||||
#ifdef TWSI_DEBUG
|
#ifdef TWSI_DEBUG
|
||||||
|
@ -117,7 +117,17 @@ gttwsi_write_4(struct gttwsi_softc *sc, uint32_t reg, uint32_t val)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
gttwsi_read_4(struct gttwsi_softc *sc, uint32_t reg)
|
||||||
|
{
|
||||||
|
return sc->sc_reg_read(sc, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gttwsi_write_4(struct gttwsi_softc *sc, uint32_t reg, uint32_t val)
|
||||||
|
{
|
||||||
|
return sc->sc_reg_write(sc, reg, val);
|
||||||
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
void
|
void
|
||||||
|
@ -133,6 +143,11 @@ gttwsi_attach_subr(device_t self, bus_space_tag_t iot, bus_space_handle_t ioh)
|
||||||
sc->sc_bust = iot;
|
sc->sc_bust = iot;
|
||||||
sc->sc_bush = ioh;
|
sc->sc_bush = ioh;
|
||||||
|
|
||||||
|
if (sc->sc_reg_read == NULL)
|
||||||
|
sc->sc_reg_read = gttwsi_default_read_4;
|
||||||
|
if (sc->sc_reg_write == NULL)
|
||||||
|
sc->sc_reg_write = gttwsi_default_write_4;
|
||||||
|
|
||||||
mutex_init(&sc->sc_buslock, MUTEX_DEFAULT, IPL_NONE);
|
mutex_init(&sc->sc_buslock, MUTEX_DEFAULT, IPL_NONE);
|
||||||
mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_BIO);
|
mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_BIO);
|
||||||
cv_init(&sc->sc_cv, device_xname(self));
|
cv_init(&sc->sc_cv, device_xname(self));
|
||||||
|
@ -213,6 +228,8 @@ gttwsi_send_start(void *v, int flags)
|
||||||
struct gttwsi_softc *sc = v;
|
struct gttwsi_softc *sc = v;
|
||||||
int expect;
|
int expect;
|
||||||
|
|
||||||
|
KASSERT(mutex_owned(&sc->sc_buslock));
|
||||||
|
|
||||||
if (sc->sc_started)
|
if (sc->sc_started)
|
||||||
expect = STAT_RSCT;
|
expect = STAT_RSCT;
|
||||||
else
|
else
|
||||||
|
@ -228,6 +245,8 @@ gttwsi_send_stop(void *v, int flags)
|
||||||
int retry = TWSI_RETRY_COUNT;
|
int retry = TWSI_RETRY_COUNT;
|
||||||
uint32_t control;
|
uint32_t control;
|
||||||
|
|
||||||
|
KASSERT(mutex_owned(&sc->sc_buslock));
|
||||||
|
|
||||||
sc->sc_started = false;
|
sc->sc_started = false;
|
||||||
|
|
||||||
/* Interrupt is not generated for STAT_NRS. */
|
/* Interrupt is not generated for STAT_NRS. */
|
||||||
|
@ -253,6 +272,8 @@ gttwsi_initiate_xfer(void *v, i2c_addr_t addr, int flags)
|
||||||
uint32_t data, expect;
|
uint32_t data, expect;
|
||||||
int error, read;
|
int error, read;
|
||||||
|
|
||||||
|
KASSERT(mutex_owned(&sc->sc_buslock));
|
||||||
|
|
||||||
gttwsi_send_start(v, flags);
|
gttwsi_send_start(v, flags);
|
||||||
|
|
||||||
read = (flags & I2C_F_READ) != 0;
|
read = (flags & I2C_F_READ) != 0;
|
||||||
|
@ -297,6 +318,8 @@ gttwsi_read_byte(void *v, uint8_t *valp, int flags)
|
||||||
struct gttwsi_softc *sc = v;
|
struct gttwsi_softc *sc = v;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
KASSERT(mutex_owned(&sc->sc_buslock));
|
||||||
|
|
||||||
if (flags & I2C_F_LAST)
|
if (flags & I2C_F_LAST)
|
||||||
error = gttwsi_wait(sc, 0, STAT_MRRD_ANT, flags);
|
error = gttwsi_wait(sc, 0, STAT_MRRD_ANT, flags);
|
||||||
else
|
else
|
||||||
|
@ -314,6 +337,8 @@ gttwsi_write_byte(void *v, uint8_t val, int flags)
|
||||||
struct gttwsi_softc *sc = v;
|
struct gttwsi_softc *sc = v;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
KASSERT(mutex_owned(&sc->sc_buslock));
|
||||||
|
|
||||||
gttwsi_write_4(sc, TWSI_DATA, val);
|
gttwsi_write_4(sc, TWSI_DATA, val);
|
||||||
error = gttwsi_wait(sc, 0, STAT_MTDB_AR, flags);
|
error = gttwsi_wait(sc, 0, STAT_MTDB_AR, flags);
|
||||||
if (flags & I2C_F_STOP)
|
if (flags & I2C_F_STOP)
|
||||||
|
@ -328,6 +353,8 @@ gttwsi_wait(struct gttwsi_softc *sc, uint32_t control, uint32_t expect,
|
||||||
uint32_t status;
|
uint32_t status;
|
||||||
int timo, error = 0;
|
int timo, error = 0;
|
||||||
|
|
||||||
|
KASSERT(mutex_owned(&sc->sc_buslock));
|
||||||
|
|
||||||
DELAY(5);
|
DELAY(5);
|
||||||
if (!(flags & I2C_F_POLL))
|
if (!(flags & I2C_F_POLL))
|
||||||
control |= CONTROL_INTEN;
|
control |= CONTROL_INTEN;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: gttwsivar.h,v 1.2 2014/11/23 13:37:27 jmcneill Exp $ */
|
/* $NetBSD: gttwsivar.h,v 1.3 2017/10/29 14:59:05 jmcneill Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008 Eiji Kawauchi.
|
* Copyright (c) 2008 Eiji Kawauchi.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
@ -89,6 +89,9 @@ struct gttwsi_softc {
|
||||||
kcondvar_t sc_cv;
|
kcondvar_t sc_cv;
|
||||||
|
|
||||||
bool sc_iflg_rwc;
|
bool sc_iflg_rwc;
|
||||||
|
|
||||||
|
uint32_t (*sc_reg_read)(struct gttwsi_softc *, uint32_t);
|
||||||
|
void (*sc_reg_write)(struct gttwsi_softc *, uint32_t, uint32_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
void gttwsi_attach_subr(device_t, bus_space_tag_t, bus_space_handle_t);
|
void gttwsi_attach_subr(device_t, bus_space_tag_t, bus_space_handle_t);
|
||||||
|
|
Loading…
Reference in New Issue