diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2009-08-29 12:09:57 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2009-08-31 13:23:09 -0400 |
commit | bc07844a33734c4b2f32ef26d942d2f3ef9302ea (patch) | |
tree | ae8cbb6dc9a17baca82a829e77c5b7fc5781b2a5 /arch | |
parent | 3f4110a48a749a1aa1c54fb807afb3f32f49711c (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.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 41 |
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 */ |
144 | extern int timer_through_8259; | 144 | extern int timer_through_8259; |
145 | 145 | ||
146 | extern 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 */ |
92 | int mp_irq_entries; | 92 | int mp_irq_entries; |
93 | 93 | ||
94 | /* Number of legacy interrupts */ | ||
95 | static int nr_legacy_irqs __read_mostly = NR_IRQS_LEGACY; | ||
96 | /* GSI interrupts */ | ||
97 | static int nr_irqs_gsi = NR_IRQS_LEGACY; | ||
98 | |||
94 | #if defined (CONFIG_MCA) || defined (CONFIG_EISA) | 99 | #if defined (CONFIG_MCA) || defined (CONFIG_EISA) |
95 | int mp_bus_id_to_type[MAX_MP_BUSSES]; | 100 | int 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 | ||
180 | void __init io_apic_disable_legacy(void) | ||
181 | { | ||
182 | nr_legacy_irqs = 0; | ||
183 | nr_irqs_gsi = 0; | ||
184 | } | ||
185 | |||
175 | int __init arch_early_irq_init(void) | 186 | int __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 | */ |
884 | static int EISA_ELCR(unsigned int irq) | 895 | static 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 | ||
3050 | void __init setup_IO_APIC(void) | 3068 | void __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 | ||
3167 | device_initcall(ioapic_init_sysfs); | 3185 | device_initcall(ioapic_init_sysfs); |
3168 | 3186 | ||
3169 | static 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 | } |