Module Name:    src
Committed By:   jakllsch
Date:           Wed Sep 26 18:32:51 UTC 2018

Modified Files:
        src/sys/dev/ic: dwiic.c dwiic_var.h

Log Message:
Sync with OpenBSD src/sys/dev/ic/dwiic.c r1.4.

Makes split command+data write operations in the exec() function work.
cvs: ----------------------------------------------------------------------


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/ic/dwiic.c
cvs rdiff -u -r1.1 -r1.2 src/sys/dev/ic/dwiic_var.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/ic/dwiic.c
diff -u src/sys/dev/ic/dwiic.c:1.3 src/sys/dev/ic/dwiic.c:1.4
--- src/sys/dev/ic/dwiic.c:1.3	Wed Sep 26 18:06:59 2018
+++ src/sys/dev/ic/dwiic.c	Wed Sep 26 18:32:51 2018
@@ -1,6 +1,6 @@
-/* $NetBSD: dwiic.c,v 1.3 2018/09/26 18:06:59 jakllsch Exp $ */
+/* $NetBSD: dwiic.c,v 1.4 2018/09/26 18:32:51 jakllsch Exp $ */
 
-/* $OpenBSD dwiic.c,v 1.24 2017/08/17 20:41:16 kettenis Exp $ */
+/* $OpenBSD: dwiic.c,v 1.4 2018/05/23 22:08:00 kettenis Exp $ */
 
 /*-
  * Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -49,7 +49,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dwiic.c,v 1.3 2018/09/26 18:06:59 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dwiic.c,v 1.4 2018/09/26 18:32:51 jakllsch Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -188,6 +188,7 @@ dwiic_attach(struct dwiic_softc *sc)
 	mutex_init(&sc->sc_int_lock, MUTEX_DEFAULT, IPL_VM);
 	cv_init(&sc->sc_int_readwait, "dwiicr");
 	cv_init(&sc->sc_int_writewait, "dwiicw");
+	cv_init(&sc->sc_int_stopwait, "dwiics");
 
 	/* setup and attach iic bus */
 	sc->sc_i2c_tag.ic_cookie = sc;
@@ -485,7 +486,7 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
 		 * As TXFLR fills up, we need to clear it out by reading all
 		 * available data.
 		 */
-		while (tx_limit == 0 || x == len) {
+		while (I2C_OP_READ_P(op) && (tx_limit == 0 || x == len)) {
 			DPRINTF(("%s: %s: tx_limit %d, sent %d read reqs\n",
 			    device_xname(sc->sc_dev), __func__, tx_limit, x));
 
@@ -545,6 +546,33 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
 		}
 	}
 
+	if (I2C_OP_STOP_P(op) && I2C_OP_WRITE_P(op)) {
+		if (flags & I2C_F_POLL) {
+			/* wait for bus to be idle */
+			for (retries = 100; retries > 0; retries--) {
+				st = dwiic_read(sc, DW_IC_STATUS);
+				if (!(st & DW_IC_STATUS_ACTIVITY))
+					break;
+				DELAY(1000);
+			}
+			if (st & DW_IC_STATUS_ACTIVITY)
+				device_printf(sc->sc_dev, "timed out waiting "
+				    "for bus idle\n");
+		} else {
+			mutex_enter(&sc->sc_int_lock);
+			dwiic_read(sc, DW_IC_CLR_INTR);
+			dwiic_write(sc, DW_IC_INTR_MASK,
+			    DW_IC_INTR_STOP_DET);
+			if (cv_timedwait(&sc->sc_int_stopwait,
+			    &sc->sc_int_lock, hz / 2) != 0)
+				device_printf(sc->sc_dev, "timed out waiting "
+				    "for stop intr\n");
+			dwiic_write(sc, DW_IC_INTR_MASK, 0);
+			dwiic_read(sc, DW_IC_CLR_INTR);
+			mutex_exit(&sc->sc_int_lock);
+		}
+	}
+
 	return 0;
 }
 
@@ -616,6 +644,12 @@ dwiic_intr(void *arg)
 			    device_xname(sc->sc_dev), __func__));
 			cv_signal(&sc->sc_int_writewait);
 		}
+		if (stat & DW_IC_INTR_STOP_DET) {
+			dwiic_write(sc, DW_IC_INTR_MASK, 0);
+			DPRINTF(("%s: %s: waking up stopper\n",
+			    device_xname(sc->sc_dev), __func__));
+			cv_signal(&sc->sc_int_stopwait);
+		}
 		mutex_exit(&sc->sc_int_lock);
 	}
 

Index: src/sys/dev/ic/dwiic_var.h
diff -u src/sys/dev/ic/dwiic_var.h:1.1 src/sys/dev/ic/dwiic_var.h:1.2
--- src/sys/dev/ic/dwiic_var.h:1.1	Sun Dec 10 17:12:54 2017
+++ src/sys/dev/ic/dwiic_var.h	Wed Sep 26 18:32:51 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: dwiic_var.h,v 1.1 2017/12/10 17:12:54 bouyer Exp $ */
+/* $NetBSD: dwiic_var.h,v 1.2 2018/09/26 18:32:51 jakllsch Exp $ */
 
 /*-
  * Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -54,6 +54,7 @@ struct dwiic_softc {
 	kmutex_t		sc_int_lock;
 	kcondvar_t		sc_int_readwait;
 	kcondvar_t		sc_int_writewait;
+	kcondvar_t		sc_int_stopwait;
 
 	uint32_t		master_cfg;
 	uint16_t		ss_hcnt, ss_lcnt, fs_hcnt, fs_lcnt;

Reply via email to