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 | |
| 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>
| -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 | } |
