aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2009-08-29 12:09:57 -0400
committerThomas Gleixner <tglx@linutronix.de>2009-08-31 13:23:09 -0400
commitbc07844a33734c4b2f32ef26d942d2f3ef9302ea (patch)
treeae8cbb6dc9a17baca82a829e77c5b7fc5781b2a5 /arch
parent3f4110a48a749a1aa1c54fb807afb3f32f49711c (diff)
x86: Distangle ioapic and i8259
The proposed Moorestown support patches use an extra feature flag mechanism to make the ioapic work w/o an i8259. There is a much simpler solution. Most i8259 specific functions are already called dependend on the irq number less than NR_IRQS_LEGACY. Replacing that constant by a read_mostly variable which can be set to 0 by the platform setup code allows us to achieve the same without any special feature flags. That trivial change allows us to proceed with MRST w/o doing a full blown overhaul of the ioapic code which would delay MRST unduly. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/io_apic.h2
-rw-r--r--arch/x86/kernel/apic/io_apic.c41
2 files changed, 31 insertions, 12 deletions
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 2b8aeb89933a..e1f89a1a07ef 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -143,6 +143,8 @@ extern int noioapicreroute;
143/* 1 if the timer IRQ uses the '8259A Virtual Wire' mode */ 143/* 1 if the timer IRQ uses the '8259A Virtual Wire' mode */
144extern int timer_through_8259; 144extern int timer_through_8259;
145 145
146extern void io_apic_disable_legacy(void);
147
146/* 148/*
147 * If we use the IO-APIC for IRQ routing, disable automatic 149 * If we use the IO-APIC for IRQ routing, disable automatic
148 * assignment of PCI IRQ's. 150 * assignment of PCI IRQ's.
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 5f4687187ceb..6c961290a5f8 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -91,6 +91,11 @@ struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
91/* # of MP IRQ source entries */ 91/* # of MP IRQ source entries */
92int mp_irq_entries; 92int mp_irq_entries;
93 93
94/* Number of legacy interrupts */
95static int nr_legacy_irqs __read_mostly = NR_IRQS_LEGACY;
96/* GSI interrupts */
97static int nr_irqs_gsi = NR_IRQS_LEGACY;
98
94#if defined (CONFIG_MCA) || defined (CONFIG_EISA) 99#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
95int mp_bus_id_to_type[MAX_MP_BUSSES]; 100int mp_bus_id_to_type[MAX_MP_BUSSES];
96#endif 101#endif
@@ -172,6 +177,12 @@ static struct irq_cfg irq_cfgx[NR_IRQS] = {
172 [15] = { .vector = IRQ15_VECTOR, }, 177 [15] = { .vector = IRQ15_VECTOR, },
173}; 178};
174 179
180void __init io_apic_disable_legacy(void)
181{
182 nr_legacy_irqs = 0;
183 nr_irqs_gsi = 0;
184}
185
175int __init arch_early_irq_init(void) 186int __init arch_early_irq_init(void)
176{ 187{
177 struct irq_cfg *cfg; 188 struct irq_cfg *cfg;
@@ -189,7 +200,7 @@ int __init arch_early_irq_init(void)
189 desc->chip_data = &cfg[i]; 200 desc->chip_data = &cfg[i];
190 zalloc_cpumask_var_node(&cfg[i].domain, GFP_NOWAIT, node); 201 zalloc_cpumask_var_node(&cfg[i].domain, GFP_NOWAIT, node);
191 zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_NOWAIT, node); 202 zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_NOWAIT, node);
192 if (i < NR_IRQS_LEGACY) 203 if (i < nr_legacy_irqs)
193 cpumask_setall(cfg[i].domain); 204 cpumask_setall(cfg[i].domain);
194 } 205 }
195 206
@@ -883,7 +894,7 @@ static int __init find_isa_irq_apic(int irq, int type)
883 */ 894 */
884static int EISA_ELCR(unsigned int irq) 895static int EISA_ELCR(unsigned int irq)
885{ 896{
886 if (irq < NR_IRQS_LEGACY) { 897 if (irq < nr_legacy_irqs) {
887 unsigned int port = 0x4d0 + (irq >> 3); 898 unsigned int port = 0x4d0 + (irq >> 3);
888 return (inb(port) >> (irq & 7)) & 1; 899 return (inb(port) >> (irq & 7)) & 1;
889 } 900 }
@@ -1480,7 +1491,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
1480 } 1491 }
1481 1492
1482 ioapic_register_intr(irq, desc, trigger); 1493 ioapic_register_intr(irq, desc, trigger);
1483 if (irq < NR_IRQS_LEGACY) 1494 if (irq < nr_legacy_irqs)
1484 disable_8259A_irq(irq); 1495 disable_8259A_irq(irq);
1485 1496
1486 ioapic_write_entry(apic_id, pin, entry); 1497 ioapic_write_entry(apic_id, pin, entry);
@@ -1851,7 +1862,7 @@ __apicdebuginit(void) print_PIC(void)
1851 unsigned int v; 1862 unsigned int v;
1852 unsigned long flags; 1863 unsigned long flags;
1853 1864
1854 if (apic_verbosity == APIC_QUIET) 1865 if (apic_verbosity == APIC_QUIET || !nr_legacy_irqs)
1855 return; 1866 return;
1856 1867
1857 printk(KERN_DEBUG "\nprinting PIC contents\n"); 1868 printk(KERN_DEBUG "\nprinting PIC contents\n");
@@ -1914,6 +1925,10 @@ void __init enable_IO_APIC(void)
1914 spin_unlock_irqrestore(&ioapic_lock, flags); 1925 spin_unlock_irqrestore(&ioapic_lock, flags);
1915 nr_ioapic_registers[apic] = reg_01.bits.entries+1; 1926 nr_ioapic_registers[apic] = reg_01.bits.entries+1;
1916 } 1927 }
1928
1929 if (!nr_legacy_irqs)
1930 return;
1931
1917 for(apic = 0; apic < nr_ioapics; apic++) { 1932 for(apic = 0; apic < nr_ioapics; apic++) {
1918 int pin; 1933 int pin;
1919 /* See if any of the pins is in ExtINT mode */ 1934 /* See if any of the pins is in ExtINT mode */
@@ -1968,6 +1983,9 @@ void disable_IO_APIC(void)
1968 */ 1983 */
1969 clear_IO_APIC(); 1984 clear_IO_APIC();
1970 1985
1986 if (!nr_legacy_irqs)
1987 return;
1988
1971 /* 1989 /*
1972 * If the i8259 is routed through an IOAPIC 1990 * If the i8259 is routed through an IOAPIC
1973 * Put that IOAPIC in virtual wire mode 1991 * Put that IOAPIC in virtual wire mode
@@ -2198,7 +2216,7 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
2198 struct irq_cfg *cfg; 2216 struct irq_cfg *cfg;
2199 2217
2200 spin_lock_irqsave(&ioapic_lock, flags); 2218 spin_lock_irqsave(&ioapic_lock, flags);
2201 if (irq < NR_IRQS_LEGACY) { 2219 if (irq < nr_legacy_irqs) {
2202 disable_8259A_irq(irq); 2220 disable_8259A_irq(irq);
2203 if (i8259A_irq_pending(irq)) 2221 if (i8259A_irq_pending(irq))
2204 was_pending = 1; 2222 was_pending = 1;
@@ -2709,7 +2727,7 @@ static inline void init_IO_APIC_traps(void)
2709 * so default to an old-fashioned 8259 2727 * so default to an old-fashioned 8259
2710 * interrupt if we can.. 2728 * interrupt if we can..
2711 */ 2729 */
2712 if (irq < NR_IRQS_LEGACY) 2730 if (irq < nr_legacy_irqs)
2713 make_8259A_irq(irq); 2731 make_8259A_irq(irq);
2714 else 2732 else
2715 /* Strange. Oh, well.. */ 2733 /* Strange. Oh, well.. */
@@ -3045,7 +3063,7 @@ out:
3045 * the I/O APIC in all cases now. No actual device should request 3063 * the I/O APIC in all cases now. No actual device should request
3046 * it anyway. --macro 3064 * it anyway. --macro
3047 */ 3065 */
3048#define PIC_IRQS (1 << PIC_CASCADE_IR) 3066#define PIC_IRQS (1UL << PIC_CASCADE_IR)
3049 3067
3050void __init setup_IO_APIC(void) 3068void __init setup_IO_APIC(void)
3051{ 3069{
@@ -3053,8 +3071,7 @@ void __init setup_IO_APIC(void)
3053 /* 3071 /*
3054 * calling enable_IO_APIC() is moved to setup_local_APIC for BP 3072 * calling enable_IO_APIC() is moved to setup_local_APIC for BP
3055 */ 3073 */
3056 3074 io_apic_irqs = nr_legacy_irqs ? ~PIC_IRQS : ~0UL;
3057 io_apic_irqs = ~PIC_IRQS;
3058 3075
3059 apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n"); 3076 apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
3060 /* 3077 /*
@@ -3065,7 +3082,8 @@ void __init setup_IO_APIC(void)
3065 sync_Arb_IDs(); 3082 sync_Arb_IDs();
3066 setup_IO_APIC_irqs(); 3083 setup_IO_APIC_irqs();
3067 init_IO_APIC_traps(); 3084 init_IO_APIC_traps();
3068 check_timer(); 3085 if (nr_legacy_irqs)
3086 check_timer();
3069} 3087}
3070 3088
3071/* 3089/*
@@ -3166,7 +3184,6 @@ static int __init ioapic_init_sysfs(void)
3166 3184
3167device_initcall(ioapic_init_sysfs); 3185device_initcall(ioapic_init_sysfs);
3168 3186
3169static int nr_irqs_gsi = NR_IRQS_LEGACY;
3170/* 3187/*
3171 * Dynamic irq allocate and deallocation 3188 * Dynamic irq allocate and deallocation
3172 */ 3189 */
@@ -3907,7 +3924,7 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq,
3907 /* 3924 /*
3908 * IRQs < 16 are already in the irq_2_pin[] map 3925 * IRQs < 16 are already in the irq_2_pin[] map
3909 */ 3926 */
3910 if (irq >= NR_IRQS_LEGACY) { 3927 if (irq >= nr_legacy_irqs) {
3911 cfg = desc->chip_data; 3928 cfg = desc->chip_data;
3912 add_pin_to_irq_node(cfg, node, ioapic, pin); 3929 add_pin_to_irq_node(cfg, node, ioapic, pin);
3913 } 3930 }