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);

Reply via email to