Skip to content

Commit bc07844

Browse files
committed
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>
1 parent 3f4110a commit bc07844

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

arch/x86/include/asm/io_apic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ extern int noioapicreroute;
143143
/* 1 if the timer IRQ uses the '8259A Virtual Wire' mode */
144144
extern int timer_through_8259;
145145

146+
extern void io_apic_disable_legacy(void);
147+
146148
/*
147149
* If we use the IO-APIC for IRQ routing, disable automatic
148150
* assignment of PCI IRQ's.

arch/x86/kernel/apic/io_apic.c

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
9191
/* # of MP IRQ source entries */
9292
int mp_irq_entries;
9393

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+
9499
#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
95100
int mp_bus_id_to_type[MAX_MP_BUSSES];
96101
#endif
@@ -172,6 +177,12 @@ static struct irq_cfg irq_cfgx[NR_IRQS] = {
172177
[15] = { .vector = IRQ15_VECTOR, },
173178
};
174179

180+
void __init io_apic_disable_legacy(void)
181+
{
182+
nr_legacy_irqs = 0;
183+
nr_irqs_gsi = 0;
184+
}
185+
175186
int __init arch_early_irq_init(void)
176187
{
177188
struct irq_cfg *cfg;
@@ -189,7 +200,7 @@ int __init arch_early_irq_init(void)
189200
desc->chip_data = &cfg[i];
190201
zalloc_cpumask_var_node(&cfg[i].domain, GFP_NOWAIT, node);
191202
zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_NOWAIT, node);
192-
if (i < NR_IRQS_LEGACY)
203+
if (i < nr_legacy_irqs)
193204
cpumask_setall(cfg[i].domain);
194205
}
195206

@@ -883,7 +894,7 @@ static int __init find_isa_irq_apic(int irq, int type)
883894
*/
884895
static int EISA_ELCR(unsigned int irq)
885896
{
886-
if (irq < NR_IRQS_LEGACY) {
897+
if (irq < nr_legacy_irqs) {
887898
unsigned int port = 0x4d0 + (irq >> 3);
888899
return (inb(port) >> (irq & 7)) & 1;
889900
}
@@ -1480,7 +1491,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
14801491
}
14811492

14821493
ioapic_register_intr(irq, desc, trigger);
1483-
if (irq < NR_IRQS_LEGACY)
1494+
if (irq < nr_legacy_irqs)
14841495
disable_8259A_irq(irq);
14851496

14861497
ioapic_write_entry(apic_id, pin, entry);
@@ -1851,7 +1862,7 @@ __apicdebuginit(void) print_PIC(void)
18511862
unsigned int v;
18521863
unsigned long flags;
18531864

1854-
if (apic_verbosity == APIC_QUIET)
1865+
if (apic_verbosity == APIC_QUIET || !nr_legacy_irqs)
18551866
return;
18561867

18571868
printk(KERN_DEBUG "\nprinting PIC contents\n");
@@ -1914,6 +1925,10 @@ void __init enable_IO_APIC(void)
19141925
spin_unlock_irqrestore(&ioapic_lock, flags);
19151926
nr_ioapic_registers[apic] = reg_01.bits.entries+1;
19161927
}
1928+
1929+
if (!nr_legacy_irqs)
1930+
return;
1931+
19171932
for(apic = 0; apic < nr_ioapics; apic++) {
19181933
int pin;
19191934
/* See if any of the pins is in ExtINT mode */
@@ -1968,6 +1983,9 @@ void disable_IO_APIC(void)
19681983
*/
19691984
clear_IO_APIC();
19701985

1986+
if (!nr_legacy_irqs)
1987+
return;
1988+
19711989
/*
19721990
* If the i8259 is routed through an IOAPIC
19731991
* Put that IOAPIC in virtual wire mode
@@ -2198,7 +2216,7 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
21982216
struct irq_cfg *cfg;
21992217

22002218
spin_lock_irqsave(&ioapic_lock, flags);
2201-
if (irq < NR_IRQS_LEGACY) {
2219+
if (irq < nr_legacy_irqs) {
22022220
disable_8259A_irq(irq);
22032221
if (i8259A_irq_pending(irq))
22042222
was_pending = 1;
@@ -2709,7 +2727,7 @@ static inline void init_IO_APIC_traps(void)
27092727
* so default to an old-fashioned 8259
27102728
* interrupt if we can..
27112729
*/
2712-
if (irq < NR_IRQS_LEGACY)
2730+
if (irq < nr_legacy_irqs)
27132731
make_8259A_irq(irq);
27142732
else
27152733
/* Strange. Oh, well.. */
@@ -3045,16 +3063,15 @@ static inline void __init check_timer(void)
30453063
* the I/O APIC in all cases now. No actual device should request
30463064
* it anyway. --macro
30473065
*/
3048-
#define PIC_IRQS (1 << PIC_CASCADE_IR)
3066+
#define PIC_IRQS (1UL << PIC_CASCADE_IR)
30493067

30503068
void __init setup_IO_APIC(void)
30513069
{
30523070

30533071
/*
30543072
* calling enable_IO_APIC() is moved to setup_local_APIC for BP
30553073
*/
3056-
3057-
io_apic_irqs = ~PIC_IRQS;
3074+
io_apic_irqs = nr_legacy_irqs ? ~PIC_IRQS : ~0UL;
30583075

30593076
apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
30603077
/*
@@ -3065,7 +3082,8 @@ void __init setup_IO_APIC(void)
30653082
sync_Arb_IDs();
30663083
setup_IO_APIC_irqs();
30673084
init_IO_APIC_traps();
3068-
check_timer();
3085+
if (nr_legacy_irqs)
3086+
check_timer();
30693087
}
30703088

30713089
/*
@@ -3166,7 +3184,6 @@ static int __init ioapic_init_sysfs(void)
31663184

31673185
device_initcall(ioapic_init_sysfs);
31683186

3169-
static int nr_irqs_gsi = NR_IRQS_LEGACY;
31703187
/*
31713188
* Dynamic irq allocate and deallocation
31723189
*/
@@ -3907,7 +3924,7 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq,
39073924
/*
39083925
* IRQs < 16 are already in the irq_2_pin[] map
39093926
*/
3910-
if (irq >= NR_IRQS_LEGACY) {
3927+
if (irq >= nr_legacy_irqs) {
39113928
cfg = desc->chip_data;
39123929
add_pin_to_irq_node(cfg, node, ioapic, pin);
39133930
}

0 commit comments

Comments
 (0)