| From 2d150b48e8a47a4c5b831a9dc09cd48d1f342976 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 9 Jun 2021 10:14:42 +0800 |
| Subject: ACPI: resources: Add checks for ACPI IRQ override |
| |
| From: Hui Wang <hui.wang@canonical.com> |
| |
| [ Upstream commit 0ec4e55e9f571f08970ed115ec0addc691eda613 ] |
| |
| 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 <rafael.j.wysocki@intel.com> |
| Reported-by: Manuel Krause <manuelkrause@netscape.net> |
| Tested-by: Manuel Krause <manuelkrause@netscape.net> |
| Signed-off-by: Hui Wang <hui.wang@canonical.com> |
| [ rjw: Subject rewrite, changelog edits ] |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/acpi/resource.c | 9 ++++++++- |
| 1 file changed, 8 insertions(+), 1 deletion(-) |
| |
| diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c |
| index f2f5f1dc7c61..9d82440a1d75 100644 |
| --- a/drivers/acpi/resource.c |
| +++ b/drivers/acpi/resource.c |
| @@ -430,6 +430,13 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, |
| } |
| } |
| |
| +static bool irq_is_legacy(struct acpi_resource_irq *irq) |
| +{ |
| + return irq->triggering == ACPI_EDGE_SENSITIVE && |
| + irq->polarity == ACPI_ACTIVE_HIGH && |
| + irq->shareable == ACPI_EXCLUSIVE; |
| +} |
| + |
| /** |
| * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information. |
| * @ares: Input ACPI resource object. |
| @@ -468,7 +475,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, |
| } |
| acpi_dev_get_irqresource(res, irq->interrupts[index], |
| irq->triggering, irq->polarity, |
| - irq->shareable, true); |
| + irq->shareable, irq_is_legacy(irq)); |
| break; |
| case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: |
| ext_irq = &ares->data.extended_irq; |
| -- |
| 2.30.2 |
| |