ACPI: fix two IRQ8 issues in IOAPIC mode
[firefly-linux-kernel-4.4.55.git] / drivers / pnp / pnpacpi / rsparser.c
index 0e3b8d0ff06b78a3432d9846a904e2c29a1f2e75..11adab13f2b724e0c94e5561c6b47b5fde175e21 100644 (file)
@@ -75,6 +75,7 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
 {
        int i = 0;
        int irq;
+       int p, t;
 
        if (!valid_IRQ(gsi))
                return;
@@ -85,6 +86,23 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
        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);