aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp/pnpacpi/rsparser.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2008-06-27 18:56:58 -0400
committerAndi Kleen <andi@basil.nowhere.org>2008-07-16 17:27:06 -0400
commit5acf91415799025410cc0d13101340d352f34c89 (patch)
tree27b50f8db97be4d5c06dbb989fa49be928aeb38d /drivers/pnp/pnpacpi/rsparser.c
parentaee3ad815dd291a7193ab01da0f1a30c84d00061 (diff)
PNPACPI: keep disabled resources when parsing current config
When we parse a device's _CRS data (the current resource settings), we should keep track of everything we find, even if it's currently disabled or invalid. This is what we already do for ISAPNP and PNPBIOS, and it helps keep things matched up when we subsequently re-encode resources. For example, consider a device with (mem, irq0, irq1, io), where irq0 is disabled. If we drop irq0 when parsing the _CRS, we will mistakenly put irq1 in the irq0 slot when we encode resources for an _SRS call. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Len Brown <len.brown@intel.com> Signed-off-by: Andi Kleen <ak@linux.intel.com>
Diffstat (limited to 'drivers/pnp/pnpacpi/rsparser.c')
-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