superio/smsc/sch5545/acpi/superio.asl: Clear PME status bits on SCI

The SCI handler for the GPE associated with the Super I/O did not clear
the respective PME status bits resulting in the SCI reoccurring
endlessly. The /proc/interrupts reported millions of ACPI interrupts
generated in just a few minutes of uptime. The flood of interrupts
caused some units to be unusable in extreme cases once attempted to
boot Qubes OS for example. On systems like Qubes OS it had a huge
impact on performance due to many IPCs the SCIs caused under Xen.

Clear the PME bits of devices that report a PME event. Then clear
the global PME status bit at the end of SCI handler to prevent the SCI
from asserting again until a new event occurrs. With this change
the number of ACPI interrupts generated in the first minutes of uptime
settles at a few thousands.

TEST=Boot Qubes OS R4.1.2 on Dell OptiPlex 9010 SFF and check
/proc/interrupts in dom0 if the number of ACPI interrupts is only
a few thousands.

Change-Id: I64e03d268138a62b46084be41343ef7fb089dfc3
Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/78351
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Krystian Hebel <krystian.hebel@3mdeb.com>
This commit is contained in:
Michał Żygowski 2023-10-13 16:23:01 +02:00
parent 55606625bb
commit fa78ecacec
1 changed files with 25 additions and 4 deletions

View File

@ -56,7 +56,6 @@ Device(SIO1) {
Name (IOST, 0x0001) /* IO decoding status */ Name (IOST, 0x0001) /* IO decoding status */
Name (MSFG, 1) /* Mouse wake config */ Name (MSFG, 1) /* Mouse wake config */
Name (KBFG, 1) /* Keyboard wake config */ Name (KBFG, 1) /* Keyboard wake config */
Name (PMFG, 0) /* Wake config */
/* SuperIO configuration ports */ /* SuperIO configuration ports */
OperationRegion (CREG, SystemIO, SUPERIO_PNP_BASE, 0x02) OperationRegion (CREG, SystemIO, SUPERIO_PNP_BASE, 0x02)
@ -338,7 +337,6 @@ Device(SIO1) {
/* SIO wake method */ /* SIO wake method */
Method (SIOW, 1, NotSerialized) Method (SIOW, 1, NotSerialized)
{ {
PMFG = PMS1
If (Arg0 == 1) If (Arg0 == 1)
{ {
GPKM () GPKM ()
@ -362,15 +360,38 @@ Device(SIO1) {
Method (SIOH, 0, NotSerialized) Method (SIOH, 0, NotSerialized)
{ {
If (PMFG & 0x08) Local0 = PMS1
If (Local0 & 0x08)
{ {
PMS1 = 0x08
Notify (PS2K, 0x02) // Device Wake Notify (PS2K, 0x02) // Device Wake
} }
If (PMFG & 0x10) If (Local0 & 0x10)
{ {
PMS1 = 0x10
Notify (PS2M, 0x02) // Device Wake Notify (PS2M, 0x02) // Device Wake
} }
If (Local0 & 0x04)
{
PMS1 = 0x04
#ifdef SCH5545_SHOW_UARTA
Notify (UAR1, 0x02) // Device Wake
#endif
}
If (Local0 & 0x02)
{
PMS1 = 0x02
#ifdef SCH5545_SHOW_UARTB
Notify (UAR2, 0x02) // Device Wake
#endif
}
Local0 = PMES
PMES = (Local0 & 1)
} }
#endif // SCH5545_RUNTIME_BASE #endif // SCH5545_RUNTIME_BASE
#endif // SCH5545_SHOW_KBC #endif // SCH5545_SHOW_KBC