aboutsummaryrefslogtreecommitdiff
path: root/drivers/pnp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pnp')
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c39
-rw-r--r--drivers/pnp/resource.c4
2 files changed, 32 insertions, 11 deletions
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index cd0a204d96d..3c5eb374adf 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -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;
@@ -82,18 +83,27 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) &&
i < PNP_MAX_IRQ)
i++;
- if (i >= PNP_MAX_IRQ)
+ if (i >= PNP_MAX_IRQ) {
+ printk(KERN_ERR "pnpacpi: exceeded the max number of IRQ "
+ "resources: %d \n", 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;
}
-#endif
+ /*
+ * 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);
@@ -173,6 +183,9 @@ static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res,
}
res->dma_resource[i].start = dma;
res->dma_resource[i].end = dma;
+ } else {
+ printk(KERN_ERR "pnpacpi: exceeded the max number of DMA "
+ "resources: %d \n", PNP_MAX_DMA);
}
}
@@ -194,6 +207,9 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res,
}
res->port_resource[i].start = io;
res->port_resource[i].end = io + len - 1;
+ } else {
+ printk(KERN_ERR "pnpacpi: exceeded the max number of IO "
+ "resources: %d \n", PNP_MAX_PORT);
}
}
@@ -217,6 +233,9 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res,
res->mem_resource[i].start = mem;
res->mem_resource[i].end = mem + len - 1;
+ } else {
+ printk(KERN_ERR "pnpacpi: exceeded the max number of mem "
+ "resources: %d\n", PNP_MAX_MEM);
}
}
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 41d73a5e931..e50ebcffb96 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -367,8 +367,10 @@ int pnp_check_irq(struct pnp_dev *dev, int idx)
{
struct pci_dev *pci = NULL;
for_each_pci_dev(pci) {
- if (pci->irq == *irq)
+ if (pci->irq == *irq) {
+ pci_dev_put(pci);
return 0;
+ }
}
}
#endif