diff options
Diffstat (limited to 'arch/x86/kernel/apic/io_apic.c')
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 52 | 
1 files changed, 33 insertions, 19 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 3c8f9e75d03..809e1cf86d6 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -96,6 +96,11 @@ struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];  /* # of MP IRQ source entries */  int mp_irq_entries; +/* Number of legacy interrupts */ +static int nr_legacy_irqs __read_mostly = NR_IRQS_LEGACY; +/* GSI interrupts */ +static int nr_irqs_gsi = NR_IRQS_LEGACY; +  #if defined (CONFIG_MCA) || defined (CONFIG_EISA)  int mp_bus_id_to_type[MAX_MP_BUSSES];  #endif @@ -173,6 +178,12 @@ static struct irq_cfg irq_cfgx[NR_IRQS] = {  	[15] = { .vector = IRQ15_VECTOR, },  }; +void __init io_apic_disable_legacy(void) +{ +	nr_legacy_irqs = 0; +	nr_irqs_gsi = 0; +} +  int __init arch_early_irq_init(void)  {  	struct irq_cfg *cfg; @@ -190,7 +201,7 @@ int __init arch_early_irq_init(void)  		desc->chip_data = &cfg[i];  		zalloc_cpumask_var_node(&cfg[i].domain, GFP_NOWAIT, node);  		zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_NOWAIT, node); -		if (i < NR_IRQS_LEGACY) +		if (i < nr_legacy_irqs)  			cpumask_setall(cfg[i].domain);  	} @@ -867,7 +878,7 @@ static int __init find_isa_irq_apic(int irq, int type)   */  static int EISA_ELCR(unsigned int irq)  { -	if (irq < NR_IRQS_LEGACY) { +	if (irq < nr_legacy_irqs) {  		unsigned int port = 0x4d0 + (irq >> 3);  		return (inb(port) >> (irq & 7)) & 1;  	} @@ -1464,7 +1475,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq  	}  	ioapic_register_intr(irq, desc, trigger); -	if (irq < NR_IRQS_LEGACY) +	if (irq < nr_legacy_irqs)  		disable_8259A_irq(irq);  	ioapic_write_entry(apic_id, pin, entry); @@ -1831,7 +1842,7 @@ __apicdebuginit(void) print_PIC(void)  	unsigned int v;  	unsigned long flags; -	if (apic_verbosity == APIC_QUIET) +	if (apic_verbosity == APIC_QUIET || !nr_legacy_irqs)  		return;  	printk(KERN_DEBUG "\nprinting PIC contents\n"); @@ -1894,6 +1905,10 @@ void __init enable_IO_APIC(void)  		spin_unlock_irqrestore(&ioapic_lock, flags);  		nr_ioapic_registers[apic] = reg_01.bits.entries+1;  	} + +	if (!nr_legacy_irqs) +		return; +  	for(apic = 0; apic < nr_ioapics; apic++) {  		int pin;  		/* See if any of the pins is in ExtINT mode */ @@ -1948,6 +1963,9 @@ void disable_IO_APIC(void)  	 */  	clear_IO_APIC(); +	if (!nr_legacy_irqs) +		return; +  	/*  	 * If the i8259 is routed through an IOAPIC  	 * Put that IOAPIC in virtual wire mode @@ -1994,7 +2012,7 @@ void disable_IO_APIC(void)   * by Matt Domsch <Matt_Domsch@dell.com>  Tue Dec 21 12:25:05 CST 1999   */ -static void __init setup_ioapic_ids_from_mpc(void) +void __init setup_ioapic_ids_from_mpc(void)  {  	union IO_APIC_reg_00 reg_00;  	physid_mask_t phys_id_present_map; @@ -2003,9 +2021,8 @@ static void __init setup_ioapic_ids_from_mpc(void)  	unsigned char old_id;  	unsigned long flags; -	if (x86_quirks->setup_ioapic_ids && x86_quirks->setup_ioapic_ids()) +	if (acpi_ioapic)  		return; -  	/*  	 * Don't check I/O APIC IDs for xAPIC systems.  They have  	 * no meaning without the serial APIC bus. @@ -2179,7 +2196,7 @@ static unsigned int startup_ioapic_irq(unsigned int irq)  	struct irq_cfg *cfg;  	spin_lock_irqsave(&ioapic_lock, flags); -	if (irq < NR_IRQS_LEGACY) { +	if (irq < nr_legacy_irqs) {  		disable_8259A_irq(irq);  		if (i8259A_irq_pending(irq))  			was_pending = 1; @@ -2657,7 +2674,7 @@ static inline void init_IO_APIC_traps(void)  			 * so default to an old-fashioned 8259  			 * interrupt if we can..  			 */ -			if (irq < NR_IRQS_LEGACY) +			if (irq < nr_legacy_irqs)  				make_8259A_irq(irq);  			else  				/* Strange. Oh, well.. */ @@ -2993,7 +3010,7 @@ out:   * the I/O APIC in all cases now.  No actual device should request   * it anyway.  --macro   */ -#define PIC_IRQS	(1 << PIC_CASCADE_IR) +#define PIC_IRQS	(1UL << PIC_CASCADE_IR)  void __init setup_IO_APIC(void)  { @@ -3001,21 +3018,19 @@ void __init setup_IO_APIC(void)  	/*  	 * calling enable_IO_APIC() is moved to setup_local_APIC for BP  	 */ - -	io_apic_irqs = ~PIC_IRQS; +	io_apic_irqs = nr_legacy_irqs ? ~PIC_IRQS : ~0UL;  	apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");  	/*           * Set up IO-APIC IRQ routing.           */ -#ifdef CONFIG_X86_32 -	if (!acpi_ioapic) -		setup_ioapic_ids_from_mpc(); -#endif +	x86_init.mpparse.setup_ioapic_ids(); +  	sync_Arb_IDs();  	setup_IO_APIC_irqs();  	init_IO_APIC_traps(); -	check_timer(); +	if (nr_legacy_irqs) +		check_timer();  }  /* @@ -3116,7 +3131,6 @@ static int __init ioapic_init_sysfs(void)  device_initcall(ioapic_init_sysfs); -static int nr_irqs_gsi = NR_IRQS_LEGACY;  /*   * Dynamic irq allocate and deallocation   */ @@ -3856,7 +3870,7 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq,  	/*  	 * IRQs < 16 are already in the irq_2_pin[] map  	 */ -	if (irq >= NR_IRQS_LEGACY) { +	if (irq >= nr_legacy_irqs) {  		cfg = desc->chip_data;  		if (add_pin_to_irq_node_nopanic(cfg, node, ioapic, pin)) {  			printk(KERN_INFO "can not add pin %d for irq %d\n",  |