# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1315.9.3 -> 1.1315.9.4 # drivers/acpi/pci_link.c 1.18 -> 1.19 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/09/18 len.brown@intel.com 1.1315.9.4 # Extended IRQ resource type for nForce (Andrew de Quincey) # -------------------------------------------- # diff -Nru a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c --- a/drivers/acpi/pci_link.c Tue Sep 23 12:31:30 2003 +++ b/drivers/acpi/pci_link.c Tue Sep 23 12:31:30 2003 @@ -315,6 +315,7 @@ struct acpi_buffer buffer = {sizeof(resource)+1, &resource}; int i = 0; int valid = 0; + int resource_type = 0; ACPI_FUNCTION_TRACE("acpi_pci_link_set"); @@ -338,20 +339,32 @@ } } + /* If IRQ<=15, first try with a "normal" IRQ descriptor. If that fails, try with + * an extended one */ + if (irq <= 15) { + resource_type = ACPI_RSTYPE_IRQ; + } else { + resource_type = ACPI_RSTYPE_EXT_IRQ; + } + +retry_programming: + memset(&resource, 0, sizeof(resource)); /* NOTE: PCI interrupts are always level / active_low / shared. But not all interrupts > 15 are PCI interrupts. Rely on the ACPI IRQ definition for parameters */ - if (irq <= 15) { + switch(resource_type) { + case ACPI_RSTYPE_IRQ: resource.res.id = ACPI_RSTYPE_IRQ; resource.res.length = sizeof(struct acpi_resource); resource.res.data.irq.edge_level = link->irq.edge_level; resource.res.data.irq.active_high_low = link->irq.active_high_low; resource.res.data.irq.number_of_interrupts = 1; resource.res.data.irq.interrupts[0] = irq; - } - else { + break; + + case ACPI_RSTYPE_EXT_IRQ: resource.res.id = ACPI_RSTYPE_EXT_IRQ; resource.res.length = sizeof(struct acpi_resource); resource.res.data.extended_irq.producer_consumer = ACPI_CONSUMER; @@ -360,11 +373,21 @@ resource.res.data.extended_irq.number_of_interrupts = 1; resource.res.data.extended_irq.interrupts[0] = irq; /* ignore resource_source, it's optional */ + break; } resource.end.id = ACPI_RSTYPE_END_TAG; /* Attempt to set the resource */ status = acpi_set_current_resources(link->handle, &buffer); + + /* if we failed and IRQ <= 15, try again with an extended descriptor */ + if (ACPI_FAILURE(status) && (resource_type == ACPI_RSTYPE_IRQ)) { + resource_type = ACPI_RSTYPE_EXT_IRQ; + printk(PREFIX "Retrying with extended IRQ descriptor\n"); + goto retry_programming; + } + + /* check for total failure */ if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SRS\n")); return_VALUE(-ENODEV); @@ -479,14 +502,14 @@ irq = link->irq.possible[0]; } - /* - * Select the best IRQ. This is done in reverse to promote - * the use of IRQs 9, 10, 11, and >15. - */ - for (i=(link->irq.possible_count-1); i>0; i--) { - if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]]) - irq = link->irq.possible[i]; - } + /* + * Select the best IRQ. This is done in reverse to promote + * the use of IRQs 9, 10, 11, and >15. + */ + for (i=(link->irq.possible_count-1); i>0; i--) { + if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]]) + irq = link->irq.possible[i]; + } /* Attempt to enable the link device at this IRQ. */ if (acpi_pci_link_set(link, irq)) {