From 28d41515a17419e83c96879f1614c309630558e1 Mon Sep 17 00:00:00 2001 From: pirofti Date: Sun, 13 Jul 2014 10:58:19 +0000 Subject: [PATCH] Start handling host channel interrupts. For now just acknowledge and clear the event to avoid interrupt storms. --- sys/arch/octeon/dev/octhci.c | 41 ++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/sys/arch/octeon/dev/octhci.c b/sys/arch/octeon/dev/octhci.c index f51c2732d82..4956bce79e7 100644 --- a/sys/arch/octeon/dev/octhci.c +++ b/sys/arch/octeon/dev/octhci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: octhci.c,v 1.14 2014/07/12 21:07:33 pirofti Exp $ */ +/* $OpenBSD: octhci.c,v 1.15 2014/07/13 10:58:19 pirofti Exp $ */ /* * Copyright (c) 2014 Paul Irofti @@ -82,6 +82,8 @@ int octhci_intr(void *); int octhci_intr1(struct octhci_softc *); int octhci_intr_host_port(struct octhci_softc *); +int octhci_intr_host_chan(struct octhci_softc *); +int octhci_intr_host_chan_n(struct octhci_softc *, int); const struct cfattach octhci_ca = { sizeof(struct octhci_softc), octhci_match, octhci_attach, @@ -403,7 +405,7 @@ octhci_intr1(struct octhci_softc *sc) } if (intsts & USBC_GINTSTS_HCHINT) { DPRINTFN(16, ("%s: host channel interrupt\n", DEVNAME(sc))); - /* XXX: add host channel irq handler */ + octhci_intr_host_chan(sc); } if (intsts & USBC_GINTSTS_PRTINT) { DPRINTFN(16, ("%s: host port interrupt\n", DEVNAME(sc))); @@ -432,6 +434,41 @@ octhci_intr_host_port(struct octhci_softc *sc) return (USBD_NORMAL_COMPLETION); } +int +octhci_intr_host_chan(struct octhci_softc *sc) +{ + int chan = 0; + uint32_t haint; + + haint = octhci_regc_read(sc, USBC_HAINT_OFFSET); + haint &= octhci_regc_read(sc, USBC_HAINTMSK_OFFSET); + + DPRINTFN(16, ("%s: haint %X\n", DEVNAME(sc), haint)); + + for (; haint != 0; haint ^= (1 << chan)) { + chan = ffs32(haint) - 1; + octhci_intr_host_chan_n(sc, chan); + } + + return (USBD_NORMAL_COMPLETION); +} + +int +octhci_intr_host_chan_n(struct octhci_softc *sc, int chan) +{ + uint32_t hcintn; + + hcintn = octhci_regc_read(sc, USBC_HCINT0_OFFSET + chan * 0x20); + hcintn &= octhci_regc_read(sc, USBC_HCINTMSK0_OFFSET + chan * 0x20); + + DPRINTFN(16, ("%s: chan %d hcintn %d\n", DEVNAME(sc), chan, hcintn)); + + /* Acknowledge */ + octhci_regc_write(sc, USBC_HCINT0_OFFSET + chan * 0x20, hcintn); + + return (USBD_NORMAL_COMPLETION); +} + inline void octhci_regn_set(struct octhci_softc *sc, bus_size_t offset, uint64_t bits) { -- 2.20.1