Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 120896
b: refs/heads/master
c: e1d3a90
h: refs/heads/master
v: v3
  • Loading branch information
Stefan Assmann authored and Ingo Molnar committed Jul 8, 2008
1 parent c99358f commit 339a500
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 426b3b8d535e3e141331dc19c40f457b997c4d6d
refs/heads/master: e1d3a90846b40ad3160bf4b648d36c6badad39ac
56 changes: 56 additions & 0 deletions trunk/drivers/acpi/pci_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,27 @@ acpi_pci_free_irq(struct acpi_prt_entry *entry,
return irq;
}

#ifdef CONFIG_X86_IO_APIC
extern int noioapicquirk;

static int bridge_has_boot_interrupt_variant(struct pci_bus *bus)
{
struct pci_bus *bus_it;

for (bus_it = bus ; bus_it ; bus_it = bus_it->parent) {
if (!bus_it->self)
return 0;

printk(KERN_INFO "vendor=%04x device=%04x\n", bus_it->self->vendor,
bus_it->self->device);

if (bus_it->self->irq_reroute_variant)
return bus_it->self->irq_reroute_variant;
}
return 0;
}
#endif /* CONFIG_X86_IO_APIC */

/*
* acpi_pci_irq_lookup
* success: return IRQ >= 0
Expand Down Expand Up @@ -413,6 +434,41 @@ acpi_pci_irq_lookup(struct pci_bus *bus,
}

ret = func(entry, triggering, polarity, link);

#ifdef CONFIG_X86_IO_APIC
/*
* Some chipsets (e.g. intel 6700PXH) generate a legacy INTx when the
* IRQ entry in the chipset's IO-APIC is masked (as, e.g. the RT kernel
* does during interrupt handling). When this INTx generation cannot be
* disabled, we reroute these interrupts to their legacy equivalent to
* get rid of spurious interrupts.
*/
if (!noioapicquirk) {
switch (bridge_has_boot_interrupt_variant(bus)) {
case 0:
/* no rerouting necessary */
break;

case INTEL_IRQ_REROUTE_VARIANT:
/*
* Remap according to INTx routing table in 6700PXH
* specs, intel order number 302628-002, section
* 2.15.2. Other chipsets (80332, ...) have the same
* mapping and are handled here as well.
*/
printk(KERN_INFO "pci irq %d -> rerouted to legacy "
"irq %d\n", ret, (ret % 4) + 16);
ret = (ret % 4) + 16;
break;

default:
printk(KERN_INFO "not rerouting irq %d to legacy irq: "
"unknown mapping\n", ret);
break;
}
}
#endif /* CONFIG_X86_IO_APIC */

return ret;
}

Expand Down
28 changes: 28 additions & 0 deletions trunk/drivers/pci/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -1364,6 +1364,34 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260a, quirk_intel_pcie_pm);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260b, quirk_intel_pcie_pm);

#ifdef CONFIG_X86_IO_APIC
/*
* Boot interrupts on some chipsets cannot be turned off. For these chipsets,
* remap the original interrupt in the linux kernel to the boot interrupt, so
* that a PCI device's interrupt handler is installed on the boot interrupt
* line instead.
*/
static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev)
{
int i;

if (noioapicquirk)
return;

dev->irq_reroute_variant = INTEL_IRQ_REROUTE_VARIANT;

printk(KERN_INFO "PCI quirk: reroute interrupts for 0x%04x:0x%04x\n",
dev->vendor, dev->device);
return;
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80333_0, quirk_reroute_to_boot_interrupts_intel);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80333_1, quirk_reroute_to_boot_interrupts_intel);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0, quirk_reroute_to_boot_interrupts_intel);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_0, quirk_reroute_to_boot_interrupts_intel);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_1, quirk_reroute_to_boot_interrupts_intel);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHV, quirk_reroute_to_boot_interrupts_intel);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80332_0, quirk_reroute_to_boot_interrupts_intel);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80332_1, quirk_reroute_to_boot_interrupts_intel);

/*
* On some chipsets we can disable the generation of legacy INTx boot
* interrupts.
Expand Down
6 changes: 6 additions & 0 deletions trunk/include/linux/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ enum pci_dev_flags {
PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) 1,
};

enum pci_irq_reroute_variant {
INTEL_IRQ_REROUTE_VARIANT = 1,
MAX_IRQ_REROUTE_VARIANTS = 3
};

typedef unsigned short __bitwise pci_bus_flags_t;
enum pci_bus_flags {
PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1,
Expand Down Expand Up @@ -194,6 +199,7 @@ struct pci_dev {
unsigned int no_d1d2:1; /* only allow d0 or d3 */
unsigned int block_ucfg_access:1; /* userspace config space access is blocked */
unsigned int broken_parity_status:1; /* Device generates false positive parity */
unsigned int irq_reroute_variant:2; /* device needs IRQ rerouting variant */
unsigned int msi_enabled:1;
unsigned int msix_enabled:1;
unsigned int is_managed:1;
Expand Down

0 comments on commit 339a500

Please sign in to comment.