From owner-svn-src-head@freebsd.org Sun Nov 3 20:53:14 2019 Return-Path: Delivered-To: svn-src-head@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 CC9761A2604; Sun, 3 Nov 2019 20:53:14 +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 475p6f4yQZz4MkP; Sun, 3 Nov 2019 20:53:14 +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 8E7C01986B; Sun, 3 Nov 2019 20:53:14 +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 xA3KrEnO065049; Sun, 3 Nov 2019 20:53:14 GMT (envelope-from wulf@FreeBSD.org) Received: (from wulf@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xA3KrDLq065045; Sun, 3 Nov 2019 20:53:13 GMT (envelope-from wulf@FreeBSD.org) Message-Id: <201911032053.xA3KrDLq065045@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:53:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r354302 - 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: 354302 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 03 Nov 2019 20:53:14 -0000 Author: wulf Date: Sun Nov 3 20:53:13 2019 New Revision: 354302 URL: https://svnweb.freebsd.org/changeset/base/354302 Log: [ig4] Allow enabling of polled mode from iicbus allocation callback If controller is allocated with IIC_NOWAIT option ig4 enables polled mode for a period of allocation that makes possible to start I2C transfers from the contexts where sleeping is not allowed e.g. from ithreads or callouts. Modified: head/sys/dev/ichiic/ig4_acpi.c head/sys/dev/ichiic/ig4_iic.c head/sys/dev/ichiic/ig4_pci.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:51:22 2019 (r354301) +++ head/sys/dev/ichiic/ig4_acpi.c Sun Nov 3 20:53:13 2019 (r354302) @@ -154,7 +154,7 @@ static device_method_t ig4iic_acpi_methods[] = { /* iicbus interface */ DEVMETHOD(iicbus_transfer, ig4iic_transfer), DEVMETHOD(iicbus_reset, ig4iic_reset), - DEVMETHOD(iicbus_callback, iicbus_null_callback), + DEVMETHOD(iicbus_callback, ig4iic_callback), DEVMETHOD_END }; Modified: head/sys/dev/ichiic/ig4_iic.c ============================================================================== --- head/sys/dev/ichiic/ig4_iic.c Sun Nov 3 20:51:22 2019 (r354301) +++ head/sys/dev/ichiic/ig4_iic.c Sun Nov 3 20:53:13 2019 (r354302) @@ -72,7 +72,7 @@ __FBSDID("$FreeBSD$"); #define TRANS_PCALL 2 #define TRANS_BLOCK 3 -#define DO_POLL(sc) (cold || kdb_active || SCHEDULER_STOPPED()) +#define DO_POLL(sc) (cold || kdb_active || SCHEDULER_STOPPED() || sc->poll) static void ig4iic_start(void *xdev); static void ig4iic_intr(void *cookie); @@ -350,6 +350,7 @@ ig4iic_transfer(device_t dev, struct iic_msg *msgs, ui int unit; bool rpstart; bool stop; + bool allocated; /* * The hardware interface imposes limits on allowed I2C messages. @@ -410,7 +411,10 @@ ig4iic_transfer(device_t dev, struct iic_msg *msgs, ui return (IIC_ENOTSUPP); } - sx_xlock(&sc->call_lock); + /* Check if device is already allocated with iicbus_request_bus() */ + allocated = sx_xlocked(&sc->call_lock) != 0; + if (!allocated) + sx_xlock(&sc->call_lock); /* Debugging - dump registers. */ if (ig4_dump) { @@ -458,7 +462,8 @@ ig4iic_transfer(device_t dev, struct iic_msg *msgs, ui rpstart = !stop; } - sx_unlock(&sc->call_lock); + if (!allocated) + sx_unlock(&sc->call_lock); return (error); } @@ -466,8 +471,11 @@ int ig4iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) { ig4iic_softc_t *sc = device_get_softc(dev); + bool allocated; - sx_xlock(&sc->call_lock); + allocated = sx_xlocked(&sc->call_lock) != 0; + if (!allocated) + sx_xlock(&sc->call_lock); /* TODO handle speed configuration? */ if (oldaddr != NULL) @@ -476,8 +484,41 @@ ig4iic_reset(device_t dev, u_char speed, u_char addr, if (addr == IIC_UNKNOWN) sc->slave_valid = false; - sx_unlock(&sc->call_lock); + if (!allocated) + sx_unlock(&sc->call_lock); return (0); +} + +int +ig4iic_callback(device_t dev, int index, caddr_t data) +{ + ig4iic_softc_t *sc = device_get_softc(dev); + int error = 0; + int how; + + switch (index) { + case IIC_REQUEST_BUS: + /* force polling if ig4iic is requested with IIC_DONTWAIT */ + how = *(int *)data; + if ((how & IIC_WAIT) == 0) { + if (sx_try_xlock(&sc->call_lock) == 0) + error = IIC_EBUSBSY; + else + sc->poll = true; + } else + sx_xlock(&sc->call_lock); + break; + + case IIC_RELEASE_BUS: + sc->poll = false; + sx_unlock(&sc->call_lock); + break; + + default: + error = errno2iic(EINVAL); + } + + return (error); } /* Modified: head/sys/dev/ichiic/ig4_pci.c ============================================================================== --- head/sys/dev/ichiic/ig4_pci.c Sun Nov 3 20:51:22 2019 (r354301) +++ head/sys/dev/ichiic/ig4_pci.c Sun Nov 3 20:53:13 2019 (r354302) @@ -214,7 +214,7 @@ static device_method_t ig4iic_pci_methods[] = { DEVMETHOD(iicbus_transfer, ig4iic_transfer), DEVMETHOD(iicbus_reset, ig4iic_reset), - DEVMETHOD(iicbus_callback, iicbus_null_callback), + DEVMETHOD(iicbus_callback, ig4iic_callback), DEVMETHOD_END }; Modified: head/sys/dev/ichiic/ig4_var.h ============================================================================== --- head/sys/dev/ichiic/ig4_var.h Sun Nov 3 20:51:22 2019 (r354301) +++ head/sys/dev/ichiic/ig4_var.h Sun Nov 3 20:53:13 2019 (r354302) @@ -67,6 +67,7 @@ struct ig4iic_softc { int slave_valid : 1; int read_started : 1; int write_started : 1; + int poll: 1; /* * Locking semantics: @@ -95,5 +96,6 @@ int ig4iic_detach(ig4iic_softc_t *sc); /* iicbus methods */ extern iicbus_transfer_t ig4iic_transfer; extern iicbus_reset_t ig4iic_reset; +extern iicbus_callback_t ig4iic_callback; #endif /* _ICHIIC_IG4_VAR_H_ */