Date: Sun, 3 Nov 2019 20:53:13 +0000 (UTC) From: Vladimir Kondratyev <wulf@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r354302 - head/sys/dev/ichiic Message-ID: <201911032053.xA3KrDLq065045@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911032053.xA3KrDLq065045>