diff options
author | Alexander Yurchenko <grange@cvs.openbsd.org> | 2005-12-25 15:46:15 +0000 |
---|---|---|
committer | Alexander Yurchenko <grange@cvs.openbsd.org> | 2005-12-25 15:46:15 +0000 |
commit | b4a39cb462aa7f31d401dc503c3a8a222db61aad (patch) | |
tree | 1d389605b3e1c09fafc657cec4b14f21dce2a0d7 /sys/dev | |
parent | 1797952a8d2353529143d6cb1c6a1bc040083599 (diff) |
Force polling if interrupts not available.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/ichiic.c | 60 | ||||
-rw-r--r-- | sys/dev/pci/piixpm.c | 21 |
2 files changed, 53 insertions, 28 deletions
diff --git a/sys/dev/pci/ichiic.c b/sys/dev/pci/ichiic.c index 015c46ed77e..bdda5207234 100644 --- a/sys/dev/pci/ichiic.c +++ b/sys/dev/pci/ichiic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ichiic.c,v 1.3 2005/12/25 14:54:45 grange Exp $ */ +/* $OpenBSD: ichiic.c,v 1.4 2005/12/25 15:46:14 grange Exp $ */ /* * Copyright (c) 2005 Alexander Yurchenko <grange@openbsd.org> @@ -52,6 +52,7 @@ struct ichiic_softc { bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; void * sc_ih; + int sc_poll; struct i2c_controller sc_i2c_tag; struct lock sc_i2c_lock; @@ -109,6 +110,7 @@ ichiic_attach(struct device *parent, struct device *self, void *aux) struct ichiic_softc *sc = (struct ichiic_softc *)self; struct pci_attach_args *pa = aux; struct i2cbus_attach_args iba; + pcireg_t conf; bus_size_t iosize; pci_intr_handle_t ih; const char *intrstr = NULL; @@ -120,26 +122,35 @@ ichiic_attach(struct device *parent, struct device *self, void *aux) return; } - /* Install interrupt handler */ - if (pci_intr_map(pa, &ih)) { - printf(": can't map interrupt\n"); - goto fail; - } - intrstr = pci_intr_string(pa->pa_pc, ih); - sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ichiic_intr, - sc, sc->sc_dev.dv_xname); - if (sc->sc_ih == NULL) { - printf(": can't establish interrupt"); - if (intrstr != NULL) - printf(" at %s", intrstr); - printf("\n"); - goto fail; + /* Read configuration */ + conf = pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_SMB_HOSTC); + DPRINTF((": conf 0x%x", conf)); + + if (conf & ICH_SMB_HOSTC_SMIEN) { + printf(": SMI"); + sc->sc_poll = 1; + } else { + /* Install interrupt handler */ + if (pci_intr_map(pa, &ih)) { + printf(": can't map interrupt\n"); + goto fail; + } + intrstr = pci_intr_string(pa->pa_pc, ih); + sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, + ichiic_intr, sc, sc->sc_dev.dv_xname); + if (sc->sc_ih == NULL) { + printf(": can't establish interrupt"); + if (intrstr != NULL) + printf(" at %s", intrstr); + printf("\n"); + goto fail; + } + printf(": %s", intrstr); } - printf(": %s", intrstr); /* Enable controller */ pci_conf_write(pa->pa_pc, pa->pa_tag, ICH_SMB_HOSTC, - ICH_SMB_HOSTC_HSTEN); + conf | ICH_SMB_HOSTC_HSTEN); printf("\n"); @@ -165,7 +176,7 @@ ichiic_i2c_acquire_bus(void *cookie, int flags) { struct ichiic_softc *sc = cookie; - if (flags & I2C_F_POLL) + if (sc->sc_poll || flags & I2C_F_POLL) return (0); return (lockmgr(&sc->sc_i2c_lock, LK_EXCLUSIVE, NULL)); @@ -176,7 +187,7 @@ ichiic_i2c_release_bus(void *cookie, int flags) { struct ichiic_softc *sc = cookie; - if (flags & I2C_F_POLL) + if (sc->sc_poll || flags & I2C_F_POLL) return; lockmgr(&sc->sc_i2c_lock, LK_RELEASE, NULL); @@ -192,8 +203,12 @@ ichiic_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, int retries; DPRINTF(("%s: exec op %d, addr 0x%x, cmdlen %d, len %d, " - "flags 0x%x\n", sc->sc_dev.dv_xname, op, addr, cmdlen, - len, flags)); + "flags 0x%x, status 0x%b\n", sc->sc_dev.dv_xname, op, addr, + cmdlen, len, flags, bus_space_read_1(sc->sc_iot, sc->sc_ioh, + ICH_SMB_HS), ICH_SMB_HS_BITS)); + + if (sc->sc_poll) + flags |= I2C_F_POLL; if (!I2C_OP_STOP_P(op) || cmdlen > 1 || len > 2) return (1); @@ -252,7 +267,8 @@ ichiic_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, DELAY(ICHIIC_DELAY); } if (st & ICH_SMB_HS_BUSY) { - printf("%s: timeout\n", sc->sc_dev.dv_xname); + printf("%s: timeout, status 0x%b\n", + sc->sc_dev.dv_xname, st, ICH_SMB_HS_BITS); return (1); } ichiic_intr(sc); diff --git a/sys/dev/pci/piixpm.c b/sys/dev/pci/piixpm.c index 04ab1b5c547..8b9747c0416 100644 --- a/sys/dev/pci/piixpm.c +++ b/sys/dev/pci/piixpm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: piixpm.c,v 1.5 2005/12/25 15:04:48 grange Exp $ */ +/* $OpenBSD: piixpm.c,v 1.6 2005/12/25 15:46:14 grange Exp $ */ /* * Copyright (c) 2005 Alexander Yurchenko <grange@openbsd.org> @@ -17,7 +17,7 @@ */ /* - * Intel PIIX and compatible power management and SMBus controller driver. + * Intel PIIX and compatible SMBus controller driver. */ #include <sys/param.h> @@ -52,6 +52,7 @@ struct piixpm_softc { bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; void * sc_ih; + int sc_poll; struct i2c_controller sc_i2c_tag; struct lock sc_i2c_lock; @@ -124,8 +125,11 @@ piixpm_attach(struct device *parent, struct device *self, void *aux) conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC); DPRINTF((": conf 0x%x", conf)); - /* Install interrupt handler if IRQ enabled */ - if ((conf & PIIX_SMB_HOSTC_IRQ) == PIIX_SMB_HOSTC_IRQ) { + if ((conf & PIIX_SMB_HOSTC_SMI) == PIIX_SMB_HOSTC_SMI) { + printf(": SMI"); + sc->sc_poll = 1; + } else if ((conf & PIIX_SMB_HOSTC_IRQ) == PIIX_SMB_HOSTC_IRQ) { + /* Install interrupt handler */ if (pci_intr_map(pa, &ih)) { printf(": can't map interrupt\n"); goto fail; @@ -141,6 +145,8 @@ piixpm_attach(struct device *parent, struct device *self, void *aux) goto fail; } printf(": %s", intrstr); + } else { + sc->sc_poll = 1; } /* Enable controller */ @@ -171,7 +177,7 @@ piixpm_i2c_acquire_bus(void *cookie, int flags) { struct piixpm_softc *sc = cookie; - if (flags & I2C_F_POLL) + if (sc->sc_poll || flags & I2C_F_POLL) return (0); return (lockmgr(&sc->sc_i2c_lock, LK_EXCLUSIVE, NULL)); @@ -182,7 +188,7 @@ piixpm_i2c_release_bus(void *cookie, int flags) { struct piixpm_softc *sc = cookie; - if (flags & I2C_F_POLL) + if (sc->sc_poll || flags & I2C_F_POLL) return; lockmgr(&sc->sc_i2c_lock, LK_RELEASE, NULL); @@ -202,6 +208,9 @@ piixpm_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, cmdlen, len, flags, bus_space_read_1(sc->sc_iot, sc->sc_ioh, PIIX_SMB_HS), PIIX_SMB_HS_BITS)); + if (sc->sc_poll) + flags |= I2C_F_POLL; + if (!I2C_OP_STOP_P(op) || cmdlen > 1 || len > 2) return (1); |