|
@@ -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,15 +86,22 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
|
|
|
if (i >= PNP_MAX_IRQ)
|
|
|
return;
|
|
|
|
|
|
-#ifdef CONFIG_X86
|
|
|
- if (gsi < 16 && (triggering != ACPI_EDGE_SENSITIVE ||
|
|
|
- polarity != ACPI_ACTIVE_HIGH)) {
|
|
|
- pnp_warn("BIOS BUG: legacy PNP IRQ %d should be edge trigger, "
|
|
|
- "active high", gsi);
|
|
|
- triggering = ACPI_EDGE_SENSITIVE;
|
|
|
- polarity = ACPI_ACTIVE_HIGH;
|
|
|
+ /*
|
|
|
+ * 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;
|
|
|
+ }
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag
|
|
|
res->irq_resource[i].flags |= irq_flags(triggering, polarity);
|