aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/Kconfig24
-rw-r--r--arch/x86/include/asm/io_apic.h10
-rw-r--r--arch/x86/include/asm/pci.h2
-rw-r--r--arch/x86/pci/common.c17
4 files changed, 53 insertions, 0 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 350bee1d54dc..f4ed47db79ee 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -653,6 +653,30 @@ config X86_VISWS_APIC
653 def_bool y 653 def_bool y
654 depends on X86_32 && X86_VISWS 654 depends on X86_32 && X86_VISWS
655 655
656config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
657 bool "Reroute for broken boot IRQs"
658 default n
659 depends on X86_IO_APIC
660 help
661 This option enables a workaround that fixes a source of
662 spurious interrupts. This is recommended when threaded
663 interrupt handling is used on systems where the generation of
664 superfluous "boot interrupts" cannot be disabled.
665
666 Some chipsets generate a legacy INTx "boot IRQ" when the IRQ
667 entry in the chipset's IO-APIC is masked (as, e.g. the RT
668 kernel does during interrupt handling). On chipsets where this
669 boot IRQ generation cannot be disabled, this workaround keeps
670 the original IRQ line masked so that only the equivalent "boot
671 IRQ" is delivered to the CPUs. The workaround also tells the
672 kernel to set up the IRQ handler on the boot IRQ line. In this
673 way only one interrupt is delivered to the kernel. Otherwise
674 the spurious second interrupt may cause the kernel to bring
675 down (vital) interrupt lines.
676
677 Only affects "broken" chipsets. Interrupt sharing may be
678 increased on these systems.
679
656config X86_MCE 680config X86_MCE
657 bool "Machine Check Exception" 681 bool "Machine Check Exception"
658 depends on !X86_VOYAGER 682 depends on !X86_VOYAGER
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 6afd9933a7dd..e475e009ae5d 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -156,11 +156,21 @@ extern int sis_apic_bug;
156/* 1 if "noapic" boot option passed */ 156/* 1 if "noapic" boot option passed */
157extern int skip_ioapic_setup; 157extern int skip_ioapic_setup;
158 158
159/* 1 if "noapic" boot option passed */
160extern int noioapicquirk;
161
162/* -1 if "noapic" boot option passed */
163extern int noioapicreroute;
164
159/* 1 if the timer IRQ uses the '8259A Virtual Wire' mode */ 165/* 1 if the timer IRQ uses the '8259A Virtual Wire' mode */
160extern int timer_through_8259; 166extern int timer_through_8259;
161 167
162static inline void disable_ioapic_setup(void) 168static inline void disable_ioapic_setup(void)
163{ 169{
170#ifdef CONFIG_PCI
171 noioapicquirk = 1;
172 noioapicreroute = -1;
173#endif
164 skip_ioapic_setup = 1; 174 skip_ioapic_setup = 1;
165} 175}
166 176
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 875b38edf193..647781298e7e 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -19,6 +19,8 @@ struct pci_sysdata {
19}; 19};
20 20
21extern int pci_routeirq; 21extern int pci_routeirq;
22extern int noioapicquirk;
23extern int noioapicreroute;
22 24
23/* scan a bus after allocating a pci_sysdata for it */ 25/* scan a bus after allocating a pci_sysdata for it */
24extern struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, 26extern struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops,
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index b67732bbb85a..bb1a01f089e2 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -23,6 +23,12 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
23unsigned int pci_early_dump_regs; 23unsigned int pci_early_dump_regs;
24static int pci_bf_sort; 24static int pci_bf_sort;
25int pci_routeirq; 25int pci_routeirq;
26int noioapicquirk;
27#ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS
28int noioapicreroute = 0;
29#else
30int noioapicreroute = 1;
31#endif
26int pcibios_last_bus = -1; 32int pcibios_last_bus = -1;
27unsigned long pirq_table_addr; 33unsigned long pirq_table_addr;
28struct pci_bus *pci_root_bus; 34struct pci_bus *pci_root_bus;
@@ -519,6 +525,17 @@ char * __devinit pcibios_setup(char *str)
519 } else if (!strcmp(str, "skip_isa_align")) { 525 } else if (!strcmp(str, "skip_isa_align")) {
520 pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; 526 pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
521 return NULL; 527 return NULL;
528 } else if (!strcmp(str, "noioapicquirk")) {
529 noioapicquirk = 1;
530 return NULL;
531 } else if (!strcmp(str, "ioapicreroute")) {
532 if (noioapicreroute != -1)
533 noioapicreroute = 0;
534 return NULL;
535 } else if (!strcmp(str, "noioapicreroute")) {
536 if (noioapicreroute != -1)
537 noioapicreroute = 1;
538 return NULL;
522 } 539 }
523 return str; 540 return str;
524} 541}