Merge branch 'irq-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'irq-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (76 commits) x86, apic: Fix dummy apic read operation together with broken MP handling x86, apic: Restore irqs on fail paths x86: Print real IOAPIC version for x86-64 x86: enable_update_mptable should be a macro sparseirq: Allow early irq_desc allocation x86, io-apic: Don't mark pin_programmed early x86, irq: don't call mp_config_acpi_gsi() if update_mptable is not enabled x86, irq: update_mptable needs pci_routeirq x86: don't call read_apic_id if !cpu_has_apic x86, apic: introduce io_apic_irq_attr x86/pci: add 4 more return parameters to IO_APIC_get_PCI_irq_vector(), fix x86: read apic ID in the !acpi_lapic case x86: apic: Fixmap apic address even if apic disabled x86: display extended apic registers with print_local_APIC and cpu_debug code x86: read apic ID in the !acpi_lapic case x86: clean up and fix setup_clear/force_cpu_cap handling x86: apic: Check rev 3 fadt correctly for physical_apic bit x86/pci: update pirq_enable_irq() to setup io apic routing x86/acpi: move setup io apic routing out of CONFIG_ACPI scope x86/pci: add 4 more return parameters to IO_APIC_get_PCI_irq_vector() ...
Esse commit está contido em:
@@ -889,6 +889,9 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (io_apic_assign_pci_irqs)
|
||||
return 0;
|
||||
|
||||
/* Find IRQ routing entry */
|
||||
|
||||
if (!pirq_table)
|
||||
@@ -1039,56 +1042,15 @@ static void __init pcibios_fixup_irqs(void)
|
||||
pirq_penalty[dev->irq]++;
|
||||
}
|
||||
|
||||
if (io_apic_assign_pci_irqs)
|
||||
return;
|
||||
|
||||
dev = NULL;
|
||||
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
|
||||
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
|
||||
if (!pin)
|
||||
continue;
|
||||
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
/*
|
||||
* Recalculate IRQ numbers if we use the I/O APIC.
|
||||
*/
|
||||
if (io_apic_assign_pci_irqs) {
|
||||
int irq;
|
||||
|
||||
/*
|
||||
* interrupt pins are numbered starting from 1
|
||||
*/
|
||||
irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
|
||||
PCI_SLOT(dev->devfn), pin - 1);
|
||||
/*
|
||||
* Busses behind bridges are typically not listed in the
|
||||
* MP-table. In this case we have to look up the IRQ
|
||||
* based on the parent bus, parent slot, and pin number.
|
||||
* The SMP code detects such bridged busses itself so we
|
||||
* should get into this branch reliably.
|
||||
*/
|
||||
if (irq < 0 && dev->bus->parent) {
|
||||
/* go back to the bridge */
|
||||
struct pci_dev *bridge = dev->bus->self;
|
||||
int bus;
|
||||
|
||||
pin = pci_swizzle_interrupt_pin(dev, pin);
|
||||
bus = bridge->bus->number;
|
||||
irq = IO_APIC_get_PCI_irq_vector(bus,
|
||||
PCI_SLOT(bridge->devfn), pin - 1);
|
||||
if (irq >= 0)
|
||||
dev_warn(&dev->dev,
|
||||
"using bridge %s INT %c to "
|
||||
"get IRQ %d\n",
|
||||
pci_name(bridge),
|
||||
'A' + pin - 1, irq);
|
||||
}
|
||||
if (irq >= 0) {
|
||||
dev_info(&dev->dev,
|
||||
"PCI->APIC IRQ transform: INT %c "
|
||||
"-> IRQ %d\n",
|
||||
'A' + pin - 1, irq);
|
||||
dev->irq = irq;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Still no IRQ? Try to lookup one...
|
||||
*/
|
||||
@@ -1183,6 +1145,19 @@ int __init pcibios_irq_init(void)
|
||||
pcibios_enable_irq = pirq_enable_irq;
|
||||
|
||||
pcibios_fixup_irqs();
|
||||
|
||||
if (io_apic_assign_pci_irqs && pci_routeirq) {
|
||||
struct pci_dev *dev = NULL;
|
||||
/*
|
||||
* PCI IRQ routing is set up by pci_enable_device(), but we
|
||||
* also do it here in case there are still broken drivers that
|
||||
* don't use pci_enable_device().
|
||||
*/
|
||||
printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n");
|
||||
for_each_pci_dev(dev)
|
||||
pirq_enable_irq(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1213,16 +1188,23 @@ void pcibios_penalize_isa_irq(int irq, int active)
|
||||
static int pirq_enable_irq(struct pci_dev *dev)
|
||||
{
|
||||
u8 pin;
|
||||
struct pci_dev *temp_dev;
|
||||
|
||||
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
|
||||
if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) {
|
||||
if (pin && !pcibios_lookup_irq(dev, 1)) {
|
||||
char *msg = "";
|
||||
|
||||
if (io_apic_assign_pci_irqs) {
|
||||
int irq;
|
||||
if (!io_apic_assign_pci_irqs && dev->irq)
|
||||
return 0;
|
||||
|
||||
irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin - 1);
|
||||
if (io_apic_assign_pci_irqs) {
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
struct pci_dev *temp_dev;
|
||||
int irq;
|
||||
struct io_apic_irq_attr irq_attr;
|
||||
|
||||
irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
|
||||
PCI_SLOT(dev->devfn),
|
||||
pin - 1, &irq_attr);
|
||||
/*
|
||||
* Busses behind bridges are typically not listed in the MP-table.
|
||||
* In this case we have to look up the IRQ based on the parent bus,
|
||||
@@ -1235,7 +1217,8 @@ static int pirq_enable_irq(struct pci_dev *dev)
|
||||
|
||||
pin = pci_swizzle_interrupt_pin(dev, pin);
|
||||
irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
|
||||
PCI_SLOT(bridge->devfn), pin - 1);
|
||||
PCI_SLOT(bridge->devfn),
|
||||
pin - 1, &irq_attr);
|
||||
if (irq >= 0)
|
||||
dev_warn(&dev->dev, "using bridge %s "
|
||||
"INT %c to get IRQ %d\n",
|
||||
@@ -1245,12 +1228,15 @@ static int pirq_enable_irq(struct pci_dev *dev)
|
||||
}
|
||||
dev = temp_dev;
|
||||
if (irq >= 0) {
|
||||
io_apic_set_pci_routing(&dev->dev, irq,
|
||||
&irq_attr);
|
||||
dev->irq = irq;
|
||||
dev_info(&dev->dev, "PCI->APIC IRQ transform: "
|
||||
"INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
|
||||
dev->irq = irq;
|
||||
return 0;
|
||||
} else
|
||||
msg = "; probably buggy MP table";
|
||||
#endif
|
||||
} else if (pci_probe & PCI_BIOS_IRQ_SCAN)
|
||||
msg = "";
|
||||
else
|
||||
|
Referência em uma nova issue
Block a user