From owner-svn-src-all@freebsd.org Sun Nov 3 20:42:05 2019 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id DA90C1A22ED; Sun, 3 Nov 2019 20:42:05 +0000 (UTC) (envelope-from wulf@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 475nsn5V1Jz3MS6; Sun, 3 Nov 2019 20:42:05 +0000 (UTC) (envelope-from wulf@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id A135B1967B; Sun, 3 Nov 2019 20:42:05 +0000 (UTC) (envelope-from wulf@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id xA3Kg5wt057921; Sun, 3 Nov 2019 20:42:05 GMT (envelope-from wulf@FreeBSD.org) Received: (from wulf@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xA3Kg5km057919; Sun, 3 Nov 2019 20:42:05 GMT (envelope-from wulf@FreeBSD.org) Message-Id: <201911032042.xA3Kg5km057919@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: wulf set sender to wulf@FreeBSD.org using -f From: Vladimir Kondratyev Date: Sun, 3 Nov 2019 20:42:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r354293 - head/sys/dev/ichiic X-SVN-Group: head X-SVN-Commit-Author: wulf X-SVN-Commit-Paths: head/sys/dev/ichiic X-SVN-Commit-Revision: 354293 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 03 Nov 2019 20:42:05 -0000 Author: wulf Date: Sun Nov 3 20:42:04 2019 New Revision: 354293 URL: https://svnweb.freebsd.org/changeset/base/354293 Log: [ig4] Only enable interrupts when we want them. Otherwise keep mask at 0. This avoids possible interrupt storms, depending on the state of the I2C controller before the driver attached. During attaching this clears the interrupt mask. Revert r338215 as this change makes it no-op. Obtained from: DragonflyBSD (d7c8555) Modified: head/sys/dev/ichiic/ig4_acpi.c head/sys/dev/ichiic/ig4_iic.c head/sys/dev/ichiic/ig4_var.h Modified: head/sys/dev/ichiic/ig4_acpi.c ============================================================================== --- head/sys/dev/ichiic/ig4_acpi.c Sun Nov 3 20:40:55 2019 (r354292) +++ head/sys/dev/ichiic/ig4_acpi.c Sun Nov 3 20:42:04 2019 (r354293) @@ -69,18 +69,15 @@ static int ig4iic_acpi_probe(device_t dev) { ig4iic_softc_t *sc; - char *hid; int rv; sc = device_get_softc(dev); if (acpi_disabled("ig4iic")) return (ENXIO); - rv = ACPI_ID_PROBE(device_get_parent(dev), dev, ig4iic_ids, &hid); + rv = ACPI_ID_PROBE(device_get_parent(dev), dev, ig4iic_ids, NULL); if (rv > 0) return (rv); - if (strcmp("AMDI0010", hid) == 0) - sc->access_intr_mask = 1; device_set_desc(dev, "Designware I2C Controller"); return (rv); } Modified: head/sys/dev/ichiic/ig4_iic.c ============================================================================== --- head/sys/dev/ichiic/ig4_iic.c Sun Nov 3 20:40:55 2019 (r354292) +++ head/sys/dev/ichiic/ig4_iic.c Sun Nov 3 20:42:04 2019 (r354293) @@ -98,6 +98,15 @@ reg_read(ig4iic_softc_t *sc, uint32_t reg) return (value); } +static void +set_intr_mask(ig4iic_softc_t *sc, uint32_t val) +{ + if (sc->intr_mask != val) { + reg_write(sc, IG4_REG_INTR_MASK, val); + sc->intr_mask = val; + } +} + /* * Enable or disable the controller and wait for the controller to acknowledge * the state change. @@ -113,12 +122,9 @@ set_controller(ig4iic_softc_t *sc, uint32_t ctl) * When the controller is enabled, interrupt on STOP detect * or receive character ready and clear pending interrupts. */ - if (ctl & IG4_I2C_ENABLE) { - reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET | - IG4_INTR_RX_FULL); + set_intr_mask(sc, 0); + if (ctl & IG4_I2C_ENABLE) reg_read(sc, IG4_REG_CLR_INTR); - } else - reg_write(sc, IG4_REG_INTR_MASK, 0); reg_write(sc, IG4_REG_I2C_EN, ctl); error = IIC_ETIMEOUT; @@ -196,8 +202,10 @@ wait_status(ig4iic_softc_t *sc, uint32_t status) * work, otherwise poll with the lock held. */ if (status & IG4_STATUS_RX_NOTEMPTY) { + set_intr_mask(sc, IG4_INTR_STOP_DET | IG4_INTR_RX_FULL); mtx_sleep(sc, &sc->io_lock, 0, "i2cwait", (hz + 99) / 100); /* sleep up to 10ms */ + set_intr_mask(sc, 0); count_us += 10000; } else { DELAY(25); @@ -579,6 +587,10 @@ ig4iic_attach(ig4iic_softc_t *sc) v = reg_read(sc, IG4_REG_SS_SCL_LCNT); reg_write(sc, IG4_REG_FS_SCL_LCNT, v); + reg_read(sc, IG4_REG_CLR_INTR); + reg_write(sc, IG4_REG_INTR_MASK, 0); + sc->intr_mask = 0; + /* * Program based on a 25000 Hz clock. This is a bit of a * hack (obviously). The defaults are 400 and 470 for standard @@ -725,7 +737,7 @@ ig4iic_intr(void *cookie) uint32_t status; mtx_lock(&sc->io_lock); -/* reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET);*/ + set_intr_mask(sc, 0); reg_read(sc, IG4_REG_CLR_INTR); status = reg_read(sc, IG4_REG_I2C_STA); while (status & IG4_STATUS_RX_NOTEMPTY) { @@ -733,18 +745,6 @@ ig4iic_intr(void *cookie) (uint8_t)reg_read(sc, IG4_REG_DATA_CMD); ++sc->rnext; status = reg_read(sc, IG4_REG_I2C_STA); - } - - /* - * Workaround to trigger pending interrupt if IG4_REG_INTR_STAT - * is changed after clearing it - */ - if (sc->access_intr_mask != 0) { - status = reg_read(sc, IG4_REG_INTR_MASK); - if (status != 0) { - reg_write(sc, IG4_REG_INTR_MASK, 0); - reg_write(sc, IG4_REG_INTR_MASK, status); - } } wakeup(sc); Modified: head/sys/dev/ichiic/ig4_var.h ============================================================================== --- head/sys/dev/ichiic/ig4_var.h Sun Nov 3 20:40:55 2019 (r354292) +++ head/sys/dev/ichiic/ig4_var.h Sun Nov 3 20:42:04 2019 (r354293) @@ -65,6 +65,7 @@ struct ig4iic_softc { int rnext; int rpos; char rbuf[IG4_RBUFSIZE]; + uint32_t intr_mask; int error; uint8_t last_slave; int platform_attached : 1; @@ -72,7 +73,6 @@ struct ig4iic_softc { int slave_valid : 1; int read_started : 1; int write_started : 1; - int access_intr_mask : 1; /* * Locking semantics: