diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 4 | ||||
-rw-r--r-- | arch/x86/Kconfig | 24 | ||||
-rw-r--r-- | arch/x86/pci/common.c | 8 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 2 | ||||
-rw-r--r-- | include/asm-x86/pci.h | 2 |
5 files changed, 38 insertions, 2 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index f5662b7a34d1..62b6e8067a5b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1536,6 +1536,10 @@ and is between 256 and 4096 characters. It is defined in the file | |||
1536 | primary IO-APIC for bridges that cannot disable | 1536 | primary IO-APIC for bridges that cannot disable |
1537 | boot IRQs. This fixes a source of spurious IRQs | 1537 | boot IRQs. This fixes a source of spurious IRQs |
1538 | when the system masks IRQs. | 1538 | when the system masks IRQs. |
1539 | noioapicreroute [APIC] Disable workaround that uses the | ||
1540 | boot IRQ equivalent of an IRQ that connects to | ||
1541 | a chipset where boot IRQs cannot be disabled. | ||
1542 | The opposite of ioapicreroute. | ||
1539 | biosirq [X86-32] Use PCI BIOS calls to get the interrupt | 1543 | biosirq [X86-32] Use PCI BIOS calls to get the interrupt |
1540 | routing table. These calls are known to be buggy | 1544 | routing table. These calls are known to be buggy |
1541 | on several machines and they hang the machine | 1545 | on several machines and they hang the machine |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 96e0c2ebc388..09521332636b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -665,6 +665,30 @@ config X86_VISWS_APIC | |||
665 | def_bool y | 665 | def_bool y |
666 | depends on X86_32 && X86_VISWS | 666 | depends on X86_32 && X86_VISWS |
667 | 667 | ||
668 | config X86_REROUTE_FOR_BROKEN_BOOT_IRQS | ||
669 | bool "Reroute for broken boot IRQs" | ||
670 | default n | ||
671 | depends on X86_IO_APIC | ||
672 | help | ||
673 | This option enables a workaround that fixes a source of | ||
674 | spurious interrupts. This is recommended when threaded | ||
675 | interrupt handling is used on systems where the generation of | ||
676 | superfluous "boot interrupts" cannot be disabled. | ||
677 | |||
678 | Some chipsets generate a legacy INTx "boot IRQ" when the IRQ | ||
679 | entry in the chipset's IO-APIC is masked (as, e.g. the RT | ||
680 | kernel does during interrupt handling). On chipsets where this | ||
681 | boot IRQ generation cannot be disabled, this workaround keeps | ||
682 | the original IRQ line masked so that only the equivalent "boot | ||
683 | IRQ" is delivered to the CPUs. The workaround also tells the | ||
684 | kernel to set up the IRQ handler on the boot IRQ line. In this | ||
685 | way only one interrupt is delivered to the kernel. Otherwise | ||
686 | the spurious second interrupt may cause the kernel to bring | ||
687 | down (vital) interrupt lines. | ||
688 | |||
689 | Only affects "broken" chipsets. Interrupt sharing may be | ||
690 | increased on these systems. | ||
691 | |||
668 | config X86_MCE | 692 | config X86_MCE |
669 | bool "Machine Check Exception" | 693 | bool "Machine Check Exception" |
670 | depends on !X86_VOYAGER | 694 | depends on !X86_VOYAGER |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 1485a26ddcef..bb1a01f089e2 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -24,7 +24,11 @@ unsigned int pci_early_dump_regs; | |||
24 | static int pci_bf_sort; | 24 | static int pci_bf_sort; |
25 | int pci_routeirq; | 25 | int pci_routeirq; |
26 | int noioapicquirk; | 26 | int noioapicquirk; |
27 | #ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS | ||
28 | int noioapicreroute = 0; | ||
29 | #else | ||
27 | int noioapicreroute = 1; | 30 | int noioapicreroute = 1; |
31 | #endif | ||
28 | int pcibios_last_bus = -1; | 32 | int pcibios_last_bus = -1; |
29 | unsigned long pirq_table_addr; | 33 | unsigned long pirq_table_addr; |
30 | struct pci_bus *pci_root_bus; | 34 | struct pci_bus *pci_root_bus; |
@@ -528,6 +532,10 @@ char * __devinit pcibios_setup(char *str) | |||
528 | if (noioapicreroute != -1) | 532 | if (noioapicreroute != -1) |
529 | noioapicreroute = 0; | 533 | noioapicreroute = 0; |
530 | return NULL; | 534 | return NULL; |
535 | } else if (!strcmp(str, "noioapicreroute")) { | ||
536 | if (noioapicreroute != -1) | ||
537 | noioapicreroute = 1; | ||
538 | return NULL; | ||
531 | } | 539 | } |
532 | return str; | 540 | return str; |
533 | } | 541 | } |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 0911b0c60b64..c880dd0bbfb5 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -1397,7 +1397,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260b, quirk_intel_pcie_pm); | |||
1397 | */ | 1397 | */ |
1398 | static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev) | 1398 | static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev) |
1399 | { | 1399 | { |
1400 | if (noioapicquirk) | 1400 | if (noioapicquirk || noioapicreroute) |
1401 | return; | 1401 | return; |
1402 | 1402 | ||
1403 | dev->irq_reroute_variant = INTEL_IRQ_REROUTE_VARIANT; | 1403 | dev->irq_reroute_variant = INTEL_IRQ_REROUTE_VARIANT; |
diff --git a/include/asm-x86/pci.h b/include/asm-x86/pci.h index 52a29f7668ef..9584d6d5eb93 100644 --- a/include/asm-x86/pci.h +++ b/include/asm-x86/pci.h | |||
@@ -20,7 +20,7 @@ struct pci_sysdata { | |||
20 | 20 | ||
21 | extern int pci_routeirq; | 21 | extern int pci_routeirq; |
22 | extern int noioapicquirk; | 22 | extern int noioapicquirk; |
23 | extern int ioapicreroute; | 23 | extern int noioapicreroute; |
24 | 24 | ||
25 | /* scan a bus after allocating a pci_sysdata for it */ | 25 | /* scan a bus after allocating a pci_sysdata for it */ |
26 | extern struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, | 26 | extern struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, |