summaryrefslogtreecommitdiffstats
path: root/sys/dev/i2c
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2016-04-10 16:43:17 +0000
committerkettenis <kettenis@openbsd.org>2016-04-10 16:43:17 +0000
commit985c1510ff2c50b7ee8345ee96c91434fbcc4990 (patch)
tree0605c03deb4463b4c44f0c9ef0a6c0946f2839d2 /sys/dev/i2c
parentSimple regression tests for rev(1), including UTF-8. (diff)
downloadwireguard-openbsd-985c1510ff2c50b7ee8345ee96c91434fbcc4990.tar.xz
wireguard-openbsd-985c1510ff2c50b7ee8345ee96c91434fbcc4990.zip
Fix layer violation in the ihidev(4) code by implementing a generic mechanism
that allows the i2c controller implementation to establish interrupts on behalf of i2c slave device drivers. Use this mechanism in dwiic(4) to let it configure the right acpi interrupt (global or gpio). Change the level to IPL_TTY as this is the appropriate level to use for keyboards and other input devices. ok jsg@
Diffstat (limited to 'sys/dev/i2c')
-rw-r--r--sys/dev/i2c/i2cvar.h13
-rw-r--r--sys/dev/i2c/ihidev.c27
2 files changed, 17 insertions, 23 deletions
diff --git a/sys/dev/i2c/i2cvar.h b/sys/dev/i2c/i2cvar.h
index 40b487c379c..7f63349db12 100644
--- a/sys/dev/i2c/i2cvar.h
+++ b/sys/dev/i2c/i2cvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: i2cvar.h,v 1.14 2016/04/02 00:56:39 jsg Exp $ */
+/* $OpenBSD: i2cvar.h,v 1.15 2016/04/10 16:43:17 kettenis Exp $ */
/* $NetBSD: i2cvar.h,v 1.1 2003/09/30 00:35:31 thorpej Exp $ */
/*
@@ -90,6 +90,9 @@ typedef struct i2c_controller {
int (*ic_initiate_xfer)(void *, i2c_addr_t, int);
int (*ic_read_byte)(void *, uint8_t *, int);
int (*ic_write_byte)(void *, uint8_t, int);
+
+ void *(*ic_intr_establish)(void *, void *, int, int (*)(void *),
+ void *, const char *);
} *i2c_tag_t;
/* Used to attach the i2c framework to the controller. */
@@ -106,11 +109,9 @@ struct i2c_attach_args {
i2c_tag_t ia_tag; /* our controller */
i2c_addr_t ia_addr; /* address of device */
int ia_size; /* size (for EEPROMs) */
- int ia_int; /* IRQ */
- int ia_int_flags; /* IRQ flags */
char *ia_name; /* chip name */
void *ia_cookie; /* pass extra info from bus to dev */
- void *acpi_gpio;
+ void *ia_intr; /* interrupt info */
};
/*
@@ -154,6 +155,10 @@ int iic_smbus_write_byte(i2c_tag_t, i2c_addr_t, uint8_t, uint8_t, int);
int iic_smbus_read_byte(i2c_tag_t, i2c_addr_t, uint8_t, uint8_t *, int);
int iic_smbus_receive_byte(i2c_tag_t, i2c_addr_t, uint8_t *, int);
+#define iic_intr_establish(ic, ih, level, func, arg, name) \
+ (*(ic)->ic_intr_establish)((ic)->ic_cookie, (ih), (level), \
+ (func), (arg), (name))
+
void iic_ignore_addr(u_int8_t addr);
#endif /* _DEV_I2C_I2CVAR_H_ */
diff --git a/sys/dev/i2c/ihidev.c b/sys/dev/i2c/ihidev.c
index 804771930a1..57724b4003d 100644
--- a/sys/dev/i2c/ihidev.c
+++ b/sys/dev/i2c/ihidev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ihidev.c,v 1.10 2016/04/02 00:56:39 jsg Exp $ */
+/* $OpenBSD: ihidev.c,v 1.11 2016/04/10 16:43:17 kettenis Exp $ */
/*
* HID-over-i2c driver
*
@@ -30,12 +30,6 @@
#include <dev/hid/hid.h>
-#if defined(__i386__) || defined(__amd64__)
-#include "acpi.h"
-#include <dev/acpi/acpivar.h>
-#include <dev/acpi/amltypes.h>
-#endif
-
/* #define IHIDEV_DEBUG */
#ifdef IHIDEV_DEBUG
@@ -114,7 +108,9 @@ ihidev_attach(struct device *parent, struct device *self, void *aux)
sc->sc_addr = ia->ia_addr;
sc->sc_hid_desc_addr = ia->ia_size;
- printf(": int %d", ia->ia_int);
+ /* XXX print proper interrupt string */
+ if (ia->ia_intr)
+ printf(": interrupt");
if (ihidev_hid_command(sc, I2C_HID_CMD_DESCR, NULL) ||
ihidev_hid_desc_parse(sc)) {
@@ -159,18 +155,11 @@ ihidev_attach(struct device *parent, struct device *self, void *aux)
sc->sc_ibuf = malloc(sc->sc_isize, M_DEVBUF, M_NOWAIT | M_ZERO);
/* register interrupt with system */
-#if NACPI > 0
- if (ia->ia_int > 0 && ia->acpi_gpio != NULL) {
- struct acpi_gpio *gpio = ia->acpi_gpio;
- gpio->intr_establish(gpio->cookie, ia->ia_int,
- ia->ia_int_flags, ihidev_intr, sc);
- } else
-#endif
- if (ia->ia_int > 0) {
- sc->sc_ih = acpi_intr_establish(ia->ia_int, ia->ia_int_flags,
- IPL_BIO, ihidev_intr, sc, sc->sc_dev.dv_xname);
+ if (ia->ia_intr) {
+ sc->sc_ih = iic_intr_establish(sc->sc_tag, ia->ia_intr,
+ IPL_TTY, ihidev_intr, sc, sc->sc_dev.dv_xname);
if (sc->sc_ih == NULL) {
- printf(", failed establishing intr\n");
+ printf(", can't establish interrupt\n");
return;
}
}