ACPI: fix two IRQ8 issues in IOAPIC mode
Use mp_irqs[] to get PNP device's interrupt polarity and trigger.
There are two reasons to do this:
1. BIOS bug for PNP interrupt
2. BIOS explictly does override
mp_irqs[] should cover all the cases.
http://bugzilla.kernel.org/show_bug.cgi?id=5243
http://bugzilla.kernel.org/show_bug.cgi?id=7679
http://bugzilla.kernel.org/show_bug.cgi?id=9153
[lenb: fixed !IOAPIC and 64-bit !SMP builds]
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 0e3b8d0..11adab1 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -75,6 +75,7 @@
{
int i = 0;
int irq;
+ int p, t;
if (!valid_IRQ(gsi))
return;
@@ -85,6 +86,23 @@
if (i >= PNP_MAX_IRQ)
return;
+ /*
+ * in IO-APIC mode, use overrided attribute. Two reasons:
+ * 1. BIOS bug in DSDT
+ * 2. BIOS uses IO-APIC mode Interrupt Source Override
+ */
+ if (!acpi_get_override_irq(gsi, &t, &p)) {
+ t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
+ p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
+
+ if (triggering != t || polarity != p) {
+ pnp_warn("IRQ %d override to %s, %s",
+ gsi, t ? "edge":"level", p ? "low":"high");
+ triggering = t;
+ polarity = p;
+ }
+ }
+
res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag
res->irq_resource[i].flags |= irq_flags(triggering, polarity);
irq = acpi_register_gsi(gsi, triggering, polarity);