aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pnp')
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c70
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