aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2022-03-16 16:09:17 +0000
committerMark Johnston <markj@FreeBSD.org>2022-03-17 19:39:00 +0000
commit077564cfdb7285ff7d256424715e563cbac36f8b (patch)
tree6f6bf1ebe3e800b2fd5db5592c107e2ee7d0d513
parent28d08dc7d051a4e058cc0004cf4dd884f87037a2 (diff)
downloadsrc-077564cfdb7285ff7d256424715e563cbac36f8b.tar.gz
src-077564cfdb7285ff7d256424715e563cbac36f8b.zip
hdac: Handle interrupts racing with device suspend
- Avoid looping forever if a concurrent reset causes a read of the interrupt status register to return all ones. - Lock the softc before reading the interrupt status, so as to avoid a similar infinite loop in hdac_one_intr(). This fixes suspend-to-S3 on some laptops. PR: 261207 Reviewed by: mav, imp Tested by: uqs MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D34117
-rw-r--r--sys/dev/sound/pci/hda/hdac.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index dc5a03e9807c..8415d63daa69 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -384,13 +384,13 @@ hdac_intr_handler(void *context)
* re-examine GIS then we can leave it set and never get an interrupt
* again.
*/
+ hdac_lock(sc);
intsts = HDAC_READ_4(&sc->mem, HDAC_INTSTS);
- while ((intsts & HDAC_INTSTS_GIS) != 0) {
- hdac_lock(sc);
+ while (intsts != 0xffffffff && (intsts & HDAC_INTSTS_GIS) != 0) {
hdac_one_intr(sc, intsts);
- hdac_unlock(sc);
intsts = HDAC_READ_4(&sc->mem, HDAC_INTSTS);
}
+ hdac_unlock(sc);
}
static void