Commit 5acf9141 authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Andi Kleen

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: default avatarBjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
Signed-off-by: default avatarAndi Kleen <ak@linux.intel.com>
parent aee3ad81
...@@ -98,8 +98,10 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, ...@@ -98,8 +98,10 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
int irq, flags; int irq, flags;
int p, t; int p, t;
if (!valid_IRQ(gsi)) if (!valid_IRQ(gsi)) {
pnp_add_irq_resource(dev, gsi, IORESOURCE_DISABLED);
return; return;
}
/* /*
* in IO-APIC mode, use overrided attribute. Two reasons: * in IO-APIC mode, use overrided attribute. Two reasons:
...@@ -248,6 +250,9 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, ...@@ -248,6 +250,9 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
* _CRS, but some firmware violates this, so parse them all. * _CRS, but some firmware violates this, so parse them all.
*/ */
irq = &res->data.irq; irq = &res->data.irq;
if (irq->interrupt_count == 0)
pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
else {
for (i = 0; i < irq->interrupt_count; i++) { for (i = 0; i < irq->interrupt_count; i++) {
pnpacpi_parse_allocated_irqresource(dev, pnpacpi_parse_allocated_irqresource(dev,
irq->interrupts[i], irq->interrupts[i],
...@@ -255,17 +260,29 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, ...@@ -255,17 +260,29 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
irq->polarity, irq->polarity,
irq->sharable); irq->sharable);
} }
/*
* The IRQ encoder puts a single interrupt in each
* descriptor, so if a _CRS descriptor has more than
* one interrupt, we won't be able to re-encode it.
*/
if (pnp_can_write(dev) && irq->interrupt_count > 1) {
dev_warn(&dev->dev, "multiple interrupts in "
"_CRS descriptor; configuration can't "
"be changed\n");
dev->capabilities &= ~PNP_WRITE;
}
}
break; break;
case ACPI_RESOURCE_TYPE_DMA: case ACPI_RESOURCE_TYPE_DMA:
dma = &res->data.dma; dma = &res->data.dma;
if (dma->channel_count > 0) { if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
flags = dma_flags(dma->type, dma->bus_master, flags = dma_flags(dma->type, dma->bus_master,
dma->transfer); dma->transfer);
if (dma->channels[0] == (u8) -1) else
flags |= IORESOURCE_DISABLED; flags = IORESOURCE_DISABLED;
pnp_add_dma_resource(dev, dma->channels[0], flags); pnp_add_dma_resource(dev, dma->channels[0], flags);
}
break; break;
case ACPI_RESOURCE_TYPE_IO: case ACPI_RESOURCE_TYPE_IO:
...@@ -331,6 +348,9 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, ...@@ -331,6 +348,9 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
if (extended_irq->producer_consumer == ACPI_PRODUCER) if (extended_irq->producer_consumer == ACPI_PRODUCER)
return AE_OK; return AE_OK;
if (extended_irq->interrupt_count == 0)
pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
else {
for (i = 0; i < extended_irq->interrupt_count; i++) { for (i = 0; i < extended_irq->interrupt_count; i++) {
pnpacpi_parse_allocated_irqresource(dev, pnpacpi_parse_allocated_irqresource(dev,
extended_irq->interrupts[i], extended_irq->interrupts[i],
...@@ -338,6 +358,20 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, ...@@ -338,6 +358,20 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
extended_irq->polarity, extended_irq->polarity,
extended_irq->sharable); extended_irq->sharable);
} }
/*
* The IRQ encoder puts a single interrupt in each
* descriptor, so if a _CRS descriptor has more than
* one interrupt, we won't be able to re-encode it.
*/
if (pnp_can_write(dev) &&
extended_irq->interrupt_count > 1) {
dev_warn(&dev->dev, "multiple interrupts in "
"_CRS descriptor; configuration can't "
"be changed\n");
dev->capabilities &= ~PNP_WRITE;
}
}
break; break;
case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment