diff options
Diffstat (limited to 'drivers/pnp/pnpacpi/rsparser.c')
-rw-r--r-- | drivers/pnp/pnpacpi/rsparser.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index cd0a204d96d1..3c5eb374adf8 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, | |||
75 | { | 75 | { |
76 | int i = 0; | 76 | int i = 0; |
77 | int irq; | 77 | int irq; |
78 | int p, t; | ||
78 | 79 | ||
79 | if (!valid_IRQ(gsi)) | 80 | if (!valid_IRQ(gsi)) |
80 | return; | 81 | return; |
@@ -82,18 +83,27 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, | |||
82 | while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) && | 83 | while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) && |
83 | i < PNP_MAX_IRQ) | 84 | i < PNP_MAX_IRQ) |
84 | i++; | 85 | i++; |
85 | if (i >= PNP_MAX_IRQ) | 86 | if (i >= PNP_MAX_IRQ) { |
87 | printk(KERN_ERR "pnpacpi: exceeded the max number of IRQ " | ||
88 | "resources: %d \n", PNP_MAX_IRQ); | ||
86 | return; | 89 | return; |
87 | |||
88 | #ifdef CONFIG_X86 | ||
89 | if (gsi < 16 && (triggering != ACPI_EDGE_SENSITIVE || | ||
90 | polarity != ACPI_ACTIVE_HIGH)) { | ||
91 | pnp_warn("BIOS BUG: legacy PNP IRQ %d should be edge trigger, " | ||
92 | "active high", gsi); | ||
93 | triggering = ACPI_EDGE_SENSITIVE; | ||
94 | polarity = ACPI_ACTIVE_HIGH; | ||
95 | } | 90 | } |
96 | #endif | 91 | /* |
92 | * in IO-APIC mode, use overrided attribute. Two reasons: | ||
93 | * 1. BIOS bug in DSDT | ||
94 | * 2. BIOS uses IO-APIC mode Interrupt Source Override | ||
95 | */ | ||
96 | if (!acpi_get_override_irq(gsi, &t, &p)) { | ||
97 | t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; | ||
98 | p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; | ||
99 | |||
100 | if (triggering != t || polarity != p) { | ||
101 | pnp_warn("IRQ %d override to %s, %s", | ||
102 | gsi, t ? "edge":"level", p ? "low":"high"); | ||
103 | triggering = t; | ||
104 | polarity = p; | ||
105 | } | ||
106 | } | ||
97 | 107 | ||
98 | res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag | 108 | res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag |
99 | res->irq_resource[i].flags |= irq_flags(triggering, polarity); | 109 | res->irq_resource[i].flags |= irq_flags(triggering, polarity); |
@@ -173,6 +183,9 @@ static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, | |||
173 | } | 183 | } |
174 | res->dma_resource[i].start = dma; | 184 | res->dma_resource[i].start = dma; |
175 | res->dma_resource[i].end = dma; | 185 | res->dma_resource[i].end = dma; |
186 | } else { | ||
187 | printk(KERN_ERR "pnpacpi: exceeded the max number of DMA " | ||
188 | "resources: %d \n", PNP_MAX_DMA); | ||
176 | } | 189 | } |
177 | } | 190 | } |
178 | 191 | ||
@@ -194,6 +207,9 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, | |||
194 | } | 207 | } |
195 | res->port_resource[i].start = io; | 208 | res->port_resource[i].start = io; |
196 | res->port_resource[i].end = io + len - 1; | 209 | res->port_resource[i].end = io + len - 1; |
210 | } else { | ||
211 | printk(KERN_ERR "pnpacpi: exceeded the max number of IO " | ||
212 | "resources: %d \n", PNP_MAX_PORT); | ||
197 | } | 213 | } |
198 | } | 214 | } |
199 | 215 | ||
@@ -217,6 +233,9 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, | |||
217 | 233 | ||
218 | res->mem_resource[i].start = mem; | 234 | res->mem_resource[i].start = mem; |
219 | res->mem_resource[i].end = mem + len - 1; | 235 | res->mem_resource[i].end = mem + len - 1; |
236 | } else { | ||
237 | printk(KERN_ERR "pnpacpi: exceeded the max number of mem " | ||
238 | "resources: %d\n", PNP_MAX_MEM); | ||
220 | } | 239 | } |
221 | } | 240 | } |
222 | 241 | ||