diff options
Diffstat (limited to 'drivers/pnp/pnpacpi/rsparser.c')
-rw-r--r-- | drivers/pnp/pnpacpi/rsparser.c | 70 |
1 files changed, 52 insertions, 18 deletions
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 9a45c25b46d2..595252b65205 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -98,8 +98,10 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, | |||
98 | int irq, flags; | 98 | int irq, flags; |
99 | int p, t; | 99 | int p, t; |
100 | 100 | ||
101 | if (!valid_IRQ(gsi)) | 101 | if (!valid_IRQ(gsi)) { |
102 | pnp_add_irq_resource(dev, gsi, IORESOURCE_DISABLED); | ||
102 | return; | 103 | return; |
104 | } | ||
103 | 105 | ||
104 | /* | 106 | /* |
105 | * in IO-APIC mode, use overrided attribute. Two reasons: | 107 | * in IO-APIC mode, use overrided attribute. Two reasons: |
@@ -248,24 +250,39 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
248 | * _CRS, but some firmware violates this, so parse them all. | 250 | * _CRS, but some firmware violates this, so parse them all. |
249 | */ | 251 | */ |
250 | irq = &res->data.irq; | 252 | irq = &res->data.irq; |
251 | for (i = 0; i < irq->interrupt_count; i++) { | 253 | if (irq->interrupt_count == 0) |
252 | pnpacpi_parse_allocated_irqresource(dev, | 254 | pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); |
253 | irq->interrupts[i], | 255 | else { |
254 | irq->triggering, | 256 | for (i = 0; i < irq->interrupt_count; i++) { |
255 | irq->polarity, | 257 | pnpacpi_parse_allocated_irqresource(dev, |
256 | irq->sharable); | 258 | irq->interrupts[i], |
259 | irq->triggering, | ||
260 | irq->polarity, | ||
261 | irq->sharable); | ||
262 | } | ||
263 | |||
264 | /* | ||
265 | * The IRQ encoder puts a single interrupt in each | ||
266 | * descriptor, so if a _CRS descriptor has more than | ||
267 | * one interrupt, we won't be able to re-encode it. | ||
268 | */ | ||
269 | if (pnp_can_write(dev) && irq->interrupt_count > 1) { | ||
270 | dev_warn(&dev->dev, "multiple interrupts in " | ||
271 | "_CRS descriptor; configuration can't " | ||
272 | "be changed\n"); | ||
273 | dev->capabilities &= ~PNP_WRITE; | ||
274 | } | ||
257 | } | 275 | } |
258 | break; | 276 | break; |
259 | 277 | ||
260 | case ACPI_RESOURCE_TYPE_DMA: | 278 | case ACPI_RESOURCE_TYPE_DMA: |
261 | dma = &res->data.dma; | 279 | dma = &res->data.dma; |
262 | if (dma->channel_count > 0) { | 280 | if (dma->channel_count > 0 && dma->channels[0] != (u8) -1) |
263 | flags = dma_flags(dma->type, dma->bus_master, | 281 | flags = dma_flags(dma->type, dma->bus_master, |
264 | dma->transfer); | 282 | dma->transfer); |
265 | if (dma->channels[0] == (u8) -1) | 283 | else |
266 | flags |= IORESOURCE_DISABLED; | 284 | flags = IORESOURCE_DISABLED; |
267 | pnp_add_dma_resource(dev, dma->channels[0], flags); | 285 | pnp_add_dma_resource(dev, dma->channels[0], flags); |
268 | } | ||
269 | break; | 286 | break; |
270 | 287 | ||
271 | case ACPI_RESOURCE_TYPE_IO: | 288 | case ACPI_RESOURCE_TYPE_IO: |
@@ -331,12 +348,29 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
331 | if (extended_irq->producer_consumer == ACPI_PRODUCER) | 348 | if (extended_irq->producer_consumer == ACPI_PRODUCER) |
332 | return AE_OK; | 349 | return AE_OK; |
333 | 350 | ||
334 | for (i = 0; i < extended_irq->interrupt_count; i++) { | 351 | if (extended_irq->interrupt_count == 0) |
335 | pnpacpi_parse_allocated_irqresource(dev, | 352 | pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); |
336 | extended_irq->interrupts[i], | 353 | else { |
337 | extended_irq->triggering, | 354 | for (i = 0; i < extended_irq->interrupt_count; i++) { |
338 | extended_irq->polarity, | 355 | pnpacpi_parse_allocated_irqresource(dev, |
339 | extended_irq->sharable); | 356 | extended_irq->interrupts[i], |
357 | extended_irq->triggering, | ||
358 | extended_irq->polarity, | ||
359 | extended_irq->sharable); | ||
360 | } | ||
361 | |||
362 | /* | ||
363 | * The IRQ encoder puts a single interrupt in each | ||
364 | * descriptor, so if a _CRS descriptor has more than | ||
365 | * one interrupt, we won't be able to re-encode it. | ||
366 | */ | ||
367 | if (pnp_can_write(dev) && | ||
368 | extended_irq->interrupt_count > 1) { | ||
369 | dev_warn(&dev->dev, "multiple interrupts in " | ||
370 | "_CRS descriptor; configuration can't " | ||
371 | "be changed\n"); | ||
372 | dev->capabilities &= ~PNP_WRITE; | ||
373 | } | ||
340 | } | 374 | } |
341 | break; | 375 | break; |
342 | 376 | ||