Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic Sync with OpenBSD src/sys/dev/ic/dwiic.c r1.4.



details:   https://anonhg.NetBSD.org/src/rev/99d73b50c22a
branches:  trunk
changeset: 836100:99d73b50c22a
user:      jakllsch <jakllsch%NetBSD.org@localhost>
date:      Wed Sep 26 18:32:51 2018 +0000

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

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

diffstat:

 sys/dev/ic/dwiic.c     |  42 ++++++++++++++++++++++++++++++++++++++----
 sys/dev/ic/dwiic_var.h |   3 ++-
 2 files changed, 40 insertions(+), 5 deletions(-)

diffs (102 lines):

diff -r ff8695d08aad -r 99d73b50c22a sys/dev/ic/dwiic.c
--- a/sys/dev/ic/dwiic.c        Wed Sep 26 18:20:59 2018 +0000
+++ b/sys/dev/ic/dwiic.c        Wed Sep 26 18:32:51 2018 +0000
@@ -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 @@
        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 @@
                 * 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 @@
                }
        }
 
+       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 @@
                            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);
        }
 
diff -r ff8695d08aad -r 99d73b50c22a sys/dev/ic/dwiic_var.h
--- a/sys/dev/ic/dwiic_var.h    Wed Sep 26 18:20:59 2018 +0000
+++ b/sys/dev/ic/dwiic_var.h    Wed Sep 26 18:32:51 2018 +0000
@@ -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 @@
        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;



Home | Main Index | Thread Index | Old Index