diff options
author | Mark Johnston <markj@FreeBSD.org> | 2022-03-16 16:09:17 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2022-03-17 19:39:00 +0000 |
commit | 077564cfdb7285ff7d256424715e563cbac36f8b (patch) | |
tree | 6f6bf1ebe3e800b2fd5db5592c107e2ee7d0d513 | |
parent | 28d08dc7d051a4e058cc0004cf4dd884f87037a2 (diff) | |
download | src-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.c | 6 |
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 |