Skip to content

Commit 0ec4e55

Browse files
jason77-wangrafaeljw
authored andcommitted
ACPI: resources: Add checks for ACPI IRQ override
The laptop keyboard doesn't work on many MEDION notebooks, but the keyboard works well under Windows and Unix. Through debugging, we found this log in the dmesg: ACPI: IRQ 1 override to edge, high pnp 00:03: Plug and Play ACPI device, IDs PNP0303 (active) And we checked the IRQ definition in the DSDT, it is: IRQ (Level, ActiveLow, Exclusive, ) {1} So the BIOS defines the keyboard IRQ to Level_Low, but the Linux kernel override it to Edge_High. If the Linux kernel is modified to skip the IRQ override, the keyboard will work normally. From the existing comment in acpi_dev_get_irqresource(), the override function only needs to be called when IRQ() or IRQNoFlags() is used to populate the resource descriptor, and according to Section 6.4.2.1 of ACPI 6.4 [1], if IRQ() is empty or IRQNoFlags() is used, the IRQ is High true, edge sensitive and non-shareable. ACPICA also assumes that to be the case (see acpi_rs_set_irq[] in rsirq.c). In accordance with the above, check 3 additional conditions (EdgeSensitive, ActiveHigh and Exclusive) when deciding whether or not to treat an ACPI_RESOURCE_TYPE_IRQ resource as "legacy", in which case the IRQ override is applicable to it. Link: https://uefi.org/specs/ACPI/6.4/06_Device_Configuration/Device_Configuration.html#irq-descriptor # [1] BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=213031 BugLink: http://bugs.launchpad.net/bugs/1909814 Suggested-by: Rafael J. Wysocki <[email protected]> Reported-by: Manuel Krause <[email protected]> Tested-by: Manuel Krause <[email protected]> Signed-off-by: Hui Wang <[email protected]> [ rjw: Subject rewrite, changelog edits ] Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 614124b commit 0ec4e55

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

drivers/acpi/resource.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,13 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
423423
}
424424
}
425425

426+
static bool irq_is_legacy(struct acpi_resource_irq *irq)
427+
{
428+
return irq->triggering == ACPI_EDGE_SENSITIVE &&
429+
irq->polarity == ACPI_ACTIVE_HIGH &&
430+
irq->shareable == ACPI_EXCLUSIVE;
431+
}
432+
426433
/**
427434
* acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
428435
* @ares: Input ACPI resource object.
@@ -461,7 +468,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
461468
}
462469
acpi_dev_get_irqresource(res, irq->interrupts[index],
463470
irq->triggering, irq->polarity,
464-
irq->shareable, true);
471+
irq->shareable, irq_is_legacy(irq));
465472
break;
466473
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
467474
ext_irq = &ares->data.extended_irq;

0 commit comments

Comments
 (0)