Skip to content

Commit

Permalink
add support for coordinating i2c bus access with iosf(4)
Browse files Browse the repository at this point in the history
if the acpi node has a _SEM property, add wrappers around the i2c
bus acquire and release handlers to try and call the iosf provided
hardware semaphore ops. this means bus accesses can be coordinate
with other parts of the platform such as the punit.

this stops my Dell Wyse 3040 from locking up.

ok kettenis@ patrick@
  • Loading branch information
dlg committed Apr 23, 2023
1 parent a72a7a2 commit 75318f5
Showing 1 changed file with 48 additions and 1 deletion.
49 changes: 48 additions & 1 deletion sys/dev/acpi/dwiic_acpi.c
@@ -1,4 +1,4 @@
/* $OpenBSD: dwiic_acpi.c,v 1.20 2022/08/31 15:14:01 kettenis Exp $ */
/* $OpenBSD: dwiic_acpi.c,v 1.21 2023/04/23 00:33:02 dlg Exp $ */
/*
* Synopsys DesignWare I2C controller
*
Expand All @@ -17,6 +17,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "iosf.h"

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
Expand All @@ -28,6 +30,7 @@
#include <dev/acpi/dsdt.h>

#include <dev/ic/dwiicvar.h>
#include <dev/ic/iosfvar.h>

struct dwiic_crs {
int irq_int;
Expand All @@ -53,6 +56,11 @@ void dwiic_acpi_power(struct dwiic_softc *, int);
void dwiic_acpi_bus_scan(struct device *,
struct i2cbus_attach_args *, void *);

#if NIOSF > 0
int dwiic_acpi_acquire_bus(void *, int);
void dwiic_acpi_release_bus(void *, int);
#endif

const struct cfattach dwiic_acpi_ca = {
sizeof(struct dwiic_softc),
dwiic_acpi_match,
Expand Down Expand Up @@ -103,6 +111,7 @@ dwiic_acpi_attach(struct device *parent, struct device *self, void *aux)
struct acpi_attach_args *aaa = aux;
struct aml_value res;
struct dwiic_crs crs;
uint64_t sem;

sc->sc_acpi = (struct acpi_softc *)parent;
sc->sc_devnode = aaa->aaa_node;
Expand Down Expand Up @@ -163,6 +172,13 @@ dwiic_acpi_attach(struct device *parent, struct device *self, void *aux)
printf(": can't establish interrupt");
}

if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode,
"_SEM", 0, NULL, &sem))
sem = 0;

if (sem)
printf(", sem");

printf("\n");

rw_init(&sc->sc_i2c_lock, "iiclk");
Expand All @@ -176,6 +192,13 @@ dwiic_acpi_attach(struct device *parent, struct device *self, void *aux)
sc->sc_i2c_tag.ic_intr_disestablish = dwiic_i2c_intr_disestablish;
sc->sc_i2c_tag.ic_intr_string = dwiic_i2c_intr_string;

#if NIOSF > 0
if (sem) {
sc->sc_i2c_tag.ic_acquire_bus = dwiic_acpi_acquire_bus;
sc->sc_i2c_tag.ic_release_bus = dwiic_acpi_release_bus;
}
#endif

bzero(&sc->sc_iba, sizeof(sc->sc_iba));
sc->sc_iba.iba_name = "iic";
sc->sc_iba.iba_tag = &sc->sc_i2c_tag;
Expand Down Expand Up @@ -547,3 +570,27 @@ dwiic_acpi_power(struct dwiic_softc *sc, int power)
dwiic_write(sc, 0x800, 1);
}
}

#if NIOSF > 0
extern int iosf_i2c_acquire(int);
extern void iosf_i2c_release(int);

int
dwiic_acpi_acquire_bus(void *cookie, int flags)
{
int rv;

rv = dwiic_i2c_acquire_bus(cookie, flags);
if (rv != 0)
return (rv);

return (iosf_i2c_acquire(flags));
}

void
dwiic_acpi_release_bus(void *cookie, int flags)
{
iosf_i2c_release(flags);
dwiic_i2c_release_bus(cookie, flags);
}
#endif /* NIOSF > 0 */

0 comments on commit 75318f5

Please sign in to comment.