Module Name: src Committed By: jmcneill Date: Sun Oct 29 14:59:05 UTC 2017
Modified Files: src/sys/dev/i2c: gttwsi_core.c gttwsivar.h Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/dev/i2c/gttwsi_core.c \ src/sys/dev/i2c/gttwsivar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/i2c/gttwsi_core.c diff -u src/sys/dev/i2c/gttwsi_core.c:1.2 src/sys/dev/i2c/gttwsi_core.c:1.3 --- src/sys/dev/i2c/gttwsi_core.c:1.2 Sun Nov 23 13:37:27 2014 +++ src/sys/dev/i2c/gttwsi_core.c Sun Oct 29 14:59:05 2017 @@ -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. * All rights reserved. @@ -66,7 +66,7 @@ */ #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 <sys/param.h> @@ -94,7 +94,7 @@ static int gttwsi_write_byte(void *v, ui static int gttwsi_wait(struct gttwsi_softc *, uint32_t, uint32_t, int); 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); #ifdef TWSI_DEBUG @@ -106,7 +106,7 @@ gttwsi_read_4(struct gttwsi_softc *sc, u } 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); #ifdef TWSI_DEBUG @@ -117,7 +117,17 @@ gttwsi_write_4(struct gttwsi_softc *sc, 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 */ void @@ -133,6 +143,11 @@ gttwsi_attach_subr(device_t self, bus_sp sc->sc_bust = iot; 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_mtx, MUTEX_DEFAULT, IPL_BIO); cv_init(&sc->sc_cv, device_xname(self)); @@ -213,6 +228,8 @@ gttwsi_send_start(void *v, int flags) struct gttwsi_softc *sc = v; int expect; + KASSERT(mutex_owned(&sc->sc_buslock)); + if (sc->sc_started) expect = STAT_RSCT; else @@ -228,6 +245,8 @@ gttwsi_send_stop(void *v, int flags) int retry = TWSI_RETRY_COUNT; uint32_t control; + KASSERT(mutex_owned(&sc->sc_buslock)); + sc->sc_started = false; /* Interrupt is not generated for STAT_NRS. */ @@ -253,6 +272,8 @@ gttwsi_initiate_xfer(void *v, i2c_addr_t uint32_t data, expect; int error, read; + KASSERT(mutex_owned(&sc->sc_buslock)); + gttwsi_send_start(v, flags); read = (flags & I2C_F_READ) != 0; @@ -297,6 +318,8 @@ gttwsi_read_byte(void *v, uint8_t *valp, struct gttwsi_softc *sc = v; int error; + KASSERT(mutex_owned(&sc->sc_buslock)); + if (flags & I2C_F_LAST) error = gttwsi_wait(sc, 0, STAT_MRRD_ANT, flags); else @@ -314,6 +337,8 @@ gttwsi_write_byte(void *v, uint8_t val, struct gttwsi_softc *sc = v; int error; + KASSERT(mutex_owned(&sc->sc_buslock)); + gttwsi_write_4(sc, TWSI_DATA, val); error = gttwsi_wait(sc, 0, STAT_MTDB_AR, flags); if (flags & I2C_F_STOP) @@ -328,6 +353,8 @@ gttwsi_wait(struct gttwsi_softc *sc, uin uint32_t status; int timo, error = 0; + KASSERT(mutex_owned(&sc->sc_buslock)); + DELAY(5); if (!(flags & I2C_F_POLL)) control |= CONTROL_INTEN; Index: src/sys/dev/i2c/gttwsivar.h diff -u src/sys/dev/i2c/gttwsivar.h:1.2 src/sys/dev/i2c/gttwsivar.h:1.3 --- src/sys/dev/i2c/gttwsivar.h:1.2 Sun Nov 23 13:37:27 2014 +++ src/sys/dev/i2c/gttwsivar.h Sun Oct 29 14:59:05 2017 @@ -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. * All rights reserved. @@ -89,6 +89,9 @@ struct gttwsi_softc { kcondvar_t sc_cv; 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);